如何使用xquery update将节点内的文本转换为子节点?

如何使用xquery update将节点内的文本转换为子节点?,xquery,xquery-update,Xquery,Xquery Update,我有一个xml文档,比如 <root> <first> First Level <second> second level <third> Third Level </third> </second> <second2> another second level </second2>

我有一个xml文档,比如

<root>
  <first>
    First Level
    <second>
      second level
       <third>
         Third Level
       </third>
    </second>
    <second2>
      another second level
    </second2>
  </first>
</root>
以下是我尝试过的:

let $a :=
<root>
  <first>
    First Level
    <second>
      second level
       <third>
         Third Level
       </third>
    </second>
    <second2>
      another second level
    </second2>
  </first>
</root>
return 
copy $i := $a
modify (
  for $x in $i/descendant-or-self::*
  return (
    if($x/text() and exists($x/*)) then (
      insert node <childtext>
        {$x/text()}
       </childtext> as first into $x
        (: here should be some code to delete the text only:)
    ) else ()
  )
)
return $i
让$a:=
一级
二级
三级
另一个第二级
返回
复制$i:=$a
修改(
对于$i/后代或自身中的$x::*
返回(
如果($x/text()且存在($x/*),则(
插入节点
{$x/text()}
作为第一个进入x美元
(:这里应该有一些只删除文本的代码:)
)else()
)
)
返回$i

我无法删除具有同级节点的文本。

如果要替换元素,只需使用
replace
构造,而不是插入新元素并删除旧元素。对我来说似乎简单得多:

copy $i := $a
modify (
  for $x in $i/descendant-or-self::*[exists(*)]/text()
  return replace node $x with <childtext>{$x}</childtext>
)
return $i
复制$i:=$a
修改(
对于$i/后代或自身中的$x::*[exists(*)]/text()
返回用{$x}替换节点$x
)
返回$i

修改后的解决方案来自@dirkk这里:

copy $i := $a
modify (
  for $x in $i/descendant-or-self::*
  return (
    if($x/text() and exists($x/*)) then (
      if(count($x/text())=1) then (
      replace node $x/text() with <child>    {$x/text()}</child>
      ) else (
        for $j at $pos in 1 to count($x/text())
        return 
       replace node $x/text()[$pos] with <child>{$x/text()[$pos]}</child>

    )


    ) else ()
  )
)
return $i
复制$i:=$a
修改(
对于$i/后代或自身中的$x::*
返回(
如果($x/text()且存在($x/*),则(
如果(count($x/text())=1,则(
将节点$x/text()替换为{$x/text()}
)否则(
对于1中$pos处的$j进行计数($x/text())
返回
将节点$x/text()[$pos]替换为{$x/text()[$pos]}
)
)else()
)
)
返回$i

再次感谢。

首先,我可以使用值text()创建节点“childtext”。现在我必须删除仍然存在的旧文本>我不能删除此文本,只能删除此文本。如果我想使值为空,其他子节点也将被删除。。。。return copy$i:=$a modify(对于$i/genderant或self中的$x::*return(如果($x/text()并且存在($x/*)),然后(将节点{$x/text()}作为第一个插入到$x中,(:这里应该以某种方式删除此文本或更新到下一级:))else())return$i请编辑此代码以解决您的问题(这里很难阅读)并且不要省略部分代码,这样它就不会再运行了(
let$a:=..
肯定不是工作代码)。您当前的代码有什么问题吗?完成!!请检查问题一次again@dirkk:如果帖子有问题,请详细描述问题,而不仅仅是发帖“你尝试过什么”。看看“你尝试过什么”的评论是否可以接受,以及“你尝试过什么”的替代品。谢谢!是的,是的,这就是我真正想要的:-)谢谢@dirkk:-)嗨,dirkk它只适用于一个文本()。这意味着它不会像ab一样工作。如何解决它。@PrakashThapa我编辑了我的答案,尽管我确实看到了你的解决方案。我更新的答案总体上比以前更好(将条件直接作为谓词放入
for
语句),并且还尊重多个
文本()
元素。我非常喜欢这种解决方案,at更容易阅读,也更高效。
copy $i := $a
modify (
  for $x in $i/descendant-or-self::*
  return (
    if($x/text() and exists($x/*)) then (
      if(count($x/text())=1) then (
      replace node $x/text() with <child>    {$x/text()}</child>
      ) else (
        for $j at $pos in 1 to count($x/text())
        return 
       replace node $x/text()[$pos] with <child>{$x/text()[$pos]}</child>

    )


    ) else ()
  )
)
return $i