在Xquery中,我想对xml示例进行排序,如下所示:
<library>
<book>
<author>abc</author>
<author>def</author>
<author>bcd</author>
</book>
<article>
<author>utc</author>
<author>abg</author>
</article>
<ebook>
<author>zerg</author>
</ebook>
</library>
我试图让输出成为..
<library>
<article>
<author>abg</author>
<author>utc</author>
</article>
<book>
<author>abc</author>
<author>bcd</author>
<author>def</author>
</book>
<ebook>
<author>zerg</author>
</ebook>
</library>
在我的查询中,我曾尝试过类似的内容:
for $s in //library
order by $s ascending, $s//* ascending
return $s
但是似乎没有接受&#34;顺序中的两个条件。
。在我提出这个问题之前,我在这里找到了类似的帖子,但它与我正在寻找的解决方案无关。任何想法??
答案 0 :(得分:1)
第一个问题是您只对<library/>
容器元素进行排序。转而覆盖其所有孩子:/library/*
。
此外,order by
您只使用&#34;库项目&#34;上的订单。等级,因此您需要订购文章,书籍,电子书,如果有多个,则按作者姓名排序。这既不希望你想要实现也不想工作,因为你不能在一系列项目之后订购(在XQuery中没有为项目序列定义订单)。
要演示正在进行的操作,请稍微修改输入并限制第一个作者:
let $xml := document {
<library>
<book>
<author>abc</author>
<author>def</author>
<author>bcd</author>
</book>
<article>
<author>utc</author>
<author>abg</author>
</article>
<article>
<author>foobar</author>
</article>
<ebook>
<author>zerg</author>
</ebook>
</library>
}
for $s in $xml//library/*
order by $s/name() ascending, ($s//*)[1] ascending
return $s
这将按预期列出所有文章,并根据第一作者的姓名对文章进行排序:
<article>
<author>foobar</author>
</article>
<article>
<author>utc</author>
<author>abg</author>
</article>
<book>
<author>abc</author>
<author>def</author>
<author>bcd</author>
</book>
<ebook>
<author>zerg</author>
</ebook>
解决方案是构建新的结果元素,因此您还可以为每个项目的作者订购:
element library {
for $item in /library/*
let $name := local-name($item)
order by $item
return element { $name } {
for $author in $item/author
order by $author
return $author
}
}
答案 1 :(得分:1)
在XSLT中,可以使用单个模板规则来完成,该规则是完全通用的,不会对XML的实际内容做出任何假设:
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="*">
<xsl:sort select="name()"/>
<xsl:sort select="."/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
答案 2 :(得分:0)
您需要嵌套查询才能执行此操作:
<library>{
for $item in /library/*
order by name($item)
return
element {node-name($item)} {
for $author in $item/author
order by $author
return $author
}
}</library>