gpt4 book ai didi

xml - 将元素序列转换为树

转载 作者:数据小太阳 更新时间:2023-10-29 02:22:01 25 4
gpt4 key购买 nike

我有一个元素列表,其中包含有关它们在 XML 树中的位置信息。 “底部”的元素,即出现在深度较低的元素之前的那些元素,包含文本。

<input>
<text n="x" xml:id="a" depth="1"/>
<div xml:id="b" depth="2"/>
<div xml:id="c" depth="3"/>
<p xml:id="e" depth="4">text</p>
<p xml:id="d" depth="4">text</p>
<p xml:id="x" depth="4">text</p>
<div xml:id="f" depth="3"/>
<lg xml:id="j" depth="4"/>
<l xml:id="k" depth="5">text</l>
<l xml:id="l" depth="5">text</l>
<p xml:id="n" depth="3">text</p>
</input>

我想在一次操作中将其重构为下面的 XML 树。

<text n="x" xml:id="a" depth="1">
<div xml:id="b" depth="2">
<div xml:id="c" depth="3">
<p xml:id="e" depth="4">text</p>
<p xml:id="d" depth="4">text</p>
<p xml:id="x" depth="4">text</p>
</div>
<div xml:id="f" depth="3">
<lg xml:id="j" depth="4">
<l xml:id="k" depth="5">text</l>
<l xml:id="l" depth="5">text</l>
</lg>
</div>
<p xml:id="n" depth="3">text</p>
</div>
</text>

我想我需要从最高深度的元素开始,即深度为 5 的所有元素,然后将它们包裹在深度 5-1 的前一个元素中,依此类推,但我无法得到我在思考如何通过这个进行递归。

@xml:ids 仅供引用。

我的问题与我之前的 stackoverflow 相反题。它类似于这个 stackoverflow问题,但我需要使用 XQuery。

最佳答案

构建一个递归构建树的函数。此代码非常通用,通过更改 local:getLevel($node) 函数,它应该适用于任意“扁平化”树。

declare function local:getLevel($node as element()) as xs:integer {
$node/@depth
};

declare function local:buildTree($nodes as element()*) as element()* {
let $level := local:getLevel($nodes[1])
(: Process all nodes of current level :)
for $node in $nodes
where $level eq local:getLevel($node)

(: Find next node of current level, if available :)
let $next := ($node/following-sibling::*[local:getLevel(.) le $level])[1]
(: All nodes between the current node and the next node on same level are children :)
let $children := $node/following-sibling::*[$node << . and (not($next) or . << $next)]

return
element { name($node) } {
(: Copy node attributes :)
$node/@*,
(: Copy all other subnodes, including text, pi, elements, comments :)
$node/node(),

(: If there are children, recursively build the subtree :)
if ($children)
then local:buildTree($children)
else ()
}
};

let $xml := document {
<input>
<text n="x" xml:id="a" depth="1"/>
<div xml:id="b" depth="2"/>
<div xml:id="c" depth="3"/>
<p xml:id="e" depth="4">text</p>
<p xml:id="d" depth="4">text</p>
<p xml:id="x" depth="4">text</p>
<div xml:id="f" depth="3"/>
<lg xml:id="j" depth="4"/>
<l xml:id="k" depth="5">text</l>
<l xml:id="l" depth="5">text</l>
<p xml:id="n" depth="3">text</p>
</input>
}

return local:buildTree($xml/input/*)

我特此将此代码发布到公共(public)领域。

如果您的 XQuery 处理器不支持增强的 FLWOR 表达式,您需要重新排序某些行;我省略了评论:

  for $node in $nodes
let $level := local:getLevel($nodes[1])
let $next := ($node/following-sibling::*[local:getLevel(.) le $level])[1]
let $children := $node/following-sibling::*[$node << . and (not($next) or . << $next)]
where $level eq local:getLevel($node)

关于xml - 将元素序列转换为树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21527660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com