【问题标题】:How to insert a new ELEMENT after a node in XQuery?如何在 XQuery 中的节点之后插入新的 ELEMENT?
【发布时间】:2018-09-24 10:04:23
【问题描述】:

我想使用下面的代码插入一个节点,但是如果我要重新运行代码,我不希望我的节点在所有元素都具有相同值的情况下重复两次-

let $doc := fn:doc("abc.xml")

(: abc.xml looks like--

<root>
  <value1>somevalue</value1>
  <value2>somevalue</value2>
  <value3>somevalue</value3>
  <value4>somevalue</value4>
  <Country>Australia</Country>
  <value6>somevalue</value6>
  <value7>somevalue</value7>
  <value8>somevalue</value8>
  <value9>somevalue</value9>
  <value10>somevalue</value10>
</root> :)

let $wrapper := if($doc//Country eq "Australia") then "AUS" 
                else if($doc//Country eq "India") then "IND"
                else ()
let $element :=  element {$wrapper}{
                    element A{"A"},
                    element B{"B"},
                    element C{"C"},
                    element D{"D"},
                    element E{"E"}
                }  

let $doc := xdmp:node-insert-after(doc("abc.xml")//value4, $element) 
return doc("abc.xml")

每当我运行此查询时,我的 ELEMENT 都会在 value4 之后插入,但我希望如果我多次运行它,那么它应该检查所有“元素”以及 $wrapper。如果它已经存在,那么它应该什么都不做,但是如果任何值发生了变化,那么它应该替换包装器或添加一个新的包装器

Example- If i am running this 2 times-

Actual Output when my country is AUSTRALIA and elements are "ABCDE"

<root>
<value1>somevalue</value1>
<value2>somevalue</value2>
<value3>somevalue</value3>
<value4>somevalue</value4>
<AUS>
    <A>A</A>
    <B>B</B>
    <C>C</C>
    <D>D</D>
    <E>E</E>
</AUS>
<AUS>
    <A>A</A>
    <B>B</B>
    <C>C</C>
    <D>D</D>
    <E>E</E>
</AUS>
<Country>Australia</Country>
<value8>somevalue</value8>
<value9>somevalue</value9>
<value10>somevalue</value10>
</root>

Expected Output- After running 2 or more times
Case-1-If the elements are "ABCDE"  and country is AUSTRALIA then it should give-

<root>
<value1>somevalue</value1>
<value2>somevalue</value2>
<value3>somevalue</value3>
<value4>somevalue</value4>
<AUS>
    <A>A</A>
    <B>B</B>
    <C>C</C>
    <D>D</D>
    <E>E</E>
</AUS>
<Country>Australia</Country>
<value8>somevalue</value8>
<value9>somevalue</value9>
<value10>somevalue</value10>
</root>

Expected Output- Case-2-If the elements are "ABCFJ" and country is AUSTRALIA then it should give-

<root>
<value1>somevalue</value1>
<value2>somevalue</value2>
<value3>somevalue</value3>
<value4>somevalue</value4>
<AUS>
    <A>A</A>
    <B>B</B>
    <C>C</C>
    <D>F</D>
    <E>J</E>
</AUS>
<Country>Australia</Country>
<value8>somevalue</value8>
<value9>somevalue</value9>
<value10>somevalue</value10>
</root>

Expected Output- Case-3-If the elements are "ABCDE" and country changed to INDIA in 2nd run then it should give-
<root>
<value1>somevalue</value1>
<value2>somevalue</value2>
<value3>somevalue</value3>
<value4>somevalue</value4>
<AUS>
    <A>A</A>
    <B>B</B>
    <C>C</C>
    <D>F</D>
    <E>E</E>
</AUS>
<IND>
    <A>A</A>
    <B>B</B>
    <C>C</C>
    <D>F</D>
    <E>E</E>
</IND>
<Country>Australia</Country>
<value8>somevalue</value8>
<value9>somevalue</value9>
<value10>somevalue</value10>
</root>

有什么建议吗??

【问题讨论】:

    标签: xml xquery xslt-2.0 marklogic


    【解决方案1】:

    在添加之前检查“AUS”元素是否存在,然后不要再次添加它,或者用 xdmp:node-replace 替换它。

    HTH!

    【讨论】:

    • @grtjn-- 我将如何处理 Case-2nd ?如果任何内部元素值发生更改,那么我只需要替换它而不是添加第二个 AUS。
    • 正如我所写,使用 xdmp:node-replace。最简单的就是替换整个 AUS 元素..
    • 明白了!!这将以类似的方式适用于所有包装国家?我可以有“n”个需要处理的国家,即;如果是同一个国家,那么我需要做-Whatever you suggested,否则我需要在其他国家元素下方添加。
    • 是的,您可以根据需要执行尽可能多的节点插入和节点替换,只要它们不在重叠节点上操作(替换您尝试插入的内容,替换您所在的父节点)正在插入一些东西,等等)..
    • replace a parent in which you are inserting something - 这就是我需要做的。 “AUS”在我第一次运行后是父级,然后在第二次运行中,如果其子元素中的任何值发生更改,我需要替换该“AUS”。
    【解决方案2】:

    问题和答案与你之前的问题How to insert a constructed XML nodes in XQuery?相同

    节点是纯文本内容、元素还是混合内容没有区别。

    【讨论】:

    • @DALDEI--感谢您的回复。您能否发布建议XQuerysn-p 是否能够处理所有三种情况?我发现很难理解它。
    【解决方案3】:

    @shalini-- 请测试以下查询,我认为这将满足您的所有要求。

      xquery version "1.0-ml";
      let $input :=doc("abc.xml")
    
        let $wrapper := if($input//Country eq "Australia") then "AUS" 
                else if($input//Country eq "India") then "IND"
                else ()
        let $element :=  element {$wrapper}{
                    element A{"A"},
                    element B{"E"},
                    element C{"D"},
                    element D{"D"},
                    element E{"E"}
                }
    
         let $result:=(
               if(fn:exists($input//AUS) and ($wrapper eq "AUS") and ($element eq 
               $input//AUS)) then ("Element already added no need to update")
               else if(fn:exists($input//AUS) and ($wrapper eq "AUS") and ($element ne 
                $input//AUS))
               then(
                     let $insert-node :=(xdmp:node-insert-after($input//value4, 
                $element),  
               <root>
              <Meassge>==Below Element added==</Meassge>
              <element>{$element}</element>
                </root>)
                     return $insert-node
                   )
              else if(fn:exists($input//IND) and ($wrapper eq "IND") and ($element eq 
              $input//IND)) then ("Element already added no need to update") 
            else if(fn:exists($input//IND) and ($wrapper eq "IND") and ($element ne 
            $input//IND))
            then(
                  let $insert-node :=(xdmp:node-insert-after($input//value4, $element),  
            <root>
           <Meassge>==Below Element added==</Meassge>
          <element>{$element}</element>
           </root>)
                 return $insert-node
                )
           else(
           let $insert-node :=(xdmp:node-insert-after($input//value4, $element),  
          <root>
          <Meassge>==Below Element added==</Meassge>
           <element>{$element}</element>
          </root>)
           return $insert-node
           )
          )
         return $result
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多