如何根据匹配和数量插入节点

问题描述 投票:0回答:1

我有一个像这样的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>
xquery distinct-values xquery-update
1个回答
0
投票

至于分组,然后只为每个组中的第一个元素插入一个新元素,看看以下是否有帮助:

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
© www.soinside.com 2019 - 2024. All rights reserved.