我有一个像这样的xml结构:
<nc>
<mod>
<grp id="d0e9f2f84">
<des>GROUP_33</des>
<num>--33</num>
<seq>33</seq>
<des2>GROUP_33</des2>
<art>
<num>15-33-101-00678</num>
</art>
</grp>
<art>
<num>15-36-072-00000</num>
</art>
<art>
<num>13-42-099-30002</num>
</art>
<art>
<num>15-42-001-45331</num>
</art>
</mod>
<mod>
<grp id="d0e9f2f84">
<des>GROUP_33</des>
<num>--33</num>
<seq>33</seq>
<des2>GROUP_33</des2>
<art>
<num>35-33-101-40678</num>
</art>
</grp>
<art>
<num>11-42-045-41002</num>
</art>
<art>
<num>12-42-101-46331</num>
</art>
</mod>
</nc>
通常正确的结构是/nc/mod/grp/art,但有时我有一些孤立的文章(艺术),例如/nc/mod/art。 我正在尝试自动化以下操作。当我有孤立文章时,插入一个节点组 (grp) 并根据文章编号 (num) 的第二个序列例如 ([0-9]{2}-42) 插入一个 grp 节点。
我尝试使用此代码片段:
let $input:=doc("file:/C:/Users/FOB/Documents/git_documentation/private/test_mod_art.xml")
return
for $ii in $input//mod/art[not(ancestor::grp)] return
if ($ii[matches(num, '^[0-5][0-9]-36')]) then
insert node <grp id="d0e1f2f21"><des>GROUP_36</des><num>--36</num><seq>36</seq><des2>GROUP_36</des2></grp> before $ii
else if ($ii[matches(num, '^[0-5][0-9]-42')]) then
insert node <grp id="d0e1f2f23"><des>GROUP_42</des><num>--42</num><seq>42</seq><des2>GROUP_42</des2></grp> before $ii
else
()
它可以工作,但是这段代码没有考虑到这样一个事实:有时我们有多个节点匹配“^[0-5][0-9]-42”,例如。 所以我需要在插入组节点之前检测它们并对其进行分组。我读过一些带有不同值函数的文章(目前我的撒克逊处理器不接受 group by 子句),尝试了一些代码,但不幸的是我没有足够的知识来理解它。 我怎样才能做到这一点,一些友好的灵魂可以专门尝试一下,以便我能够理解吗?
谢谢!
预期结果:
<nc>
<mod>
<grp id="d0e9f2f84">
<des>GROUP_33</des>
<num>--33</num>
<seq>33</seq>
<des2>GROUP_33</des2>
<art>
<num>15-33-101-00678</num>
</art>
</grp>
<grp id="d0e9f2f85">
<des>GROUP_36</des>
<num>--36</num>
<seq>36</seq>
<des2>GROUP_36</des2>
</grp>
<art>
<num>15-36-072-00000</num>
</art>
<grp id="d0e9f2f33">
<des>GROUP_42</des>
<num>--42</num>
<seq>42</seq>
<des2>GROUP_42</des2>
</grp>
<art>
<num>13-42-099-30002</num>
</art>
<art>
<num>15-42-001-45331</num>
</art>
</mod>
至于分组,然后只为每个组中的第一个元素插入一个新元素,看看以下是否有帮助:
declare ordering ordered;
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:indent 'yes';
let
$input := doc('file:/C:/Users/FOB/Documents/git_documentation/private/test_mod_art.xml'),
$group_id_map := map { '36' : 'd0e1f2f21', '42' : 'd0e1f2f23' }
return
for $art at $pos in $input//mod/art[not(ancestor::grp)][matches(num, '^[0-5][0-9]-(36|42)')]
group by $group_nr := replace($art/num, '^[0-5][0-9]-(36|42).*', '$1')
order by $pos[1]
for $art1 in $art[1]
return
insert node <grp id="{$group_id_map($group_nr)}"><des>GROUP_{$group_nr}</des><num>--{$group_nr}</num><seq>{$group_nr}</seq><des2>GROUP_{$group_nr}</des2></grp> before $art1