我仍然有一个关于通过XQuery排序xml的问题。
请检查以下代码。
原样:
<Main name = "test">
<Sample id="1">
<cal>
<tree abc="123"/>
<tree abc="789/>
<tree-order abc="456/>
</cal>
</Sample>
<Sample id="2">
<cal>
<tree abc="123"/>
<tree abc="789/>
<tree-order abc="456/>
</cal>
</Sample>
<Sample id="3">
<cal>
<tree abc="123"/>
<tree abc="789/>
<tree-order abc="456/>
</cal>
</Sample>
</Main>
我想按属性“abc”
订购成为1:
<Main name = "test">
<Sample id="1">
<cal>
<tree abc="123"/>
<tree-order abc="456/>
<tree abc="789/>
</cal>
</Sample>
<Sample id="2">
<cal>
<tree abc="123"/>
<tree-order abc="456/>
<tree abc="789/>
</cal>
</Sample>
<Sample id="3">
<cal>
<tree abc="123"/>
<tree-order abc="456/>
<tree abc="789/>
</cal>
</Sample>
</Main>
之后可以删除属性??
最终
<Main name = "test">
<Sample id="1">
<cal>
<tree />
<tree-order />
<tree />
</cal>
</Sample>
<Sample id="2">
<cal>
<tree />
<tree-order />
<tree />
</cal>
</Sample>
<Sample id="3">
<cal>
<tree />
<tree-order />
<tree />
</cal>
</Sample>
</Main>
像这样。
所以属性abc仅用于排序。
我试着喜欢这个
select @data.query('for $j in * order by number($j/@abc) return $j ')
然后它将显示xml格式而不进行排序。
有什么方法可以解决这个问题吗?
答案 0 :(得分:0)
以递归方式处理XML,以便您可以对<cal>
元素子元素执行排序并保留其祖先结构:
declare function local:sort(
$xml as element(cal)
) as element()
{
element cal {
for $e in $xml/*
order by $e/@abc
return local:dispatch($e)
}
};
declare function local:remove-atts(
$xml as element()
) as element()
{
element { node-name($xml) } {
$xml/@* except $xml/@abc,
$xml/node()
}
};
declare function local:dispatch(
$xml as element()
) as element()
{
typeswitch ($xml)
case element(cal) return local:sort($xml)
case element(tree) return local:remove-atts($xml)
case element(tree-order) return local:remove-atts($xml)
default return local:process($xml)
};
declare function local:process(
$xml as element()
) as element()
{
element { node-name($xml) } {
$xml/@*,
for $n in $xml/node()
return local:dispatch($n)
}
};
local:process($xml)