Xml 两个变量的xquery顺序不起作用

Xml 两个变量的xquery顺序不起作用,xml,sql-order-by,xquery,Xml,Sql Order By,Xquery,在Xquery中,我想对xml示例进行如下排序: <library> <book> <author>abc</author> <author>def</author> <author>bcd</author> </book> <article> <author>utc&l

在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>{
  for $item in /library/*
    order by name($item)
  return 
   element {node-name($item)} {
     for $author in $item/author
       order by $author
     return $author
   }
}</library>
{
对于$item/library/*
按名称订购($项目)
返回
元素{节点名称($item)}{
对于$item/author中的$author
$author订购
返回$author
}
}
问题1:排序库与排序库内容 第一个问题是您只对
容器元素进行排序。而是在其所有子项上循环:
/library/*

问题2:不同级别的排序 此外,
orderby
您只使用“图书馆项目”级别的订单,因此您订购的是文章、书籍、电子书,如果有多个,则按作者姓名订购这些项目。这既不是您想要实现的目标,也不起作用,因为您不能在项目序列之后进行排序(XQuery中没有对项目序列定义顺序)

为了演示发生了什么,让我们稍微修改输入并限制第一作者:


我不喜欢通过建议使用语言B的解决方案来回答使用语言a的解决方案的请求,但您在这里所做的工作属于XSLT比XQuery处理得更好的一类问题

在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>

<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>
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
  }
}
<xsl:template match="*">
  <xsl:copy>
    <xsl:apply-templates select="*">
      <xsl:sort select="name()"/>
      <xsl:sort select="."/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>