xml - XQuery 中基于变量的动态排序(排序依据)

标签 xml sorting xquery marklogic exist-db

我正在尝试在 XQuery 中实现动态排序。我目前正在使用 Saxon-PE 9.5 进行开发,但将在 eXist 和 marklogic 中使用 XQuery(或复数 xqueries),因此使用它们的模块/函数的任何答案都很好(希望其他数据库将具有相应的模块/函数) .

排序基于包含字符串序列的变量。序列中的每个字符串都是一个元素的名称和一个可选的“降序”。

我已经尝试了多种方法,但无法让任何东西按预期方式工作;特别是对于二次排序。

在下面的示例中,排序是静态的,并且具有主要排序 c(升序)和次要排序 b(降序)...

so_xquery_question.xml

<doc>
    <foo id="foo1">
        <a>a1</a>
        <b>b1</b>
        <c>c0</c>
    </foo>
    <foo id="foo2">
        <a>a2</a>
        <b>b2</b>
        <c>c0</c>
    </foo>
    <foo id="foo3">
        <a>a3</a>
        <b>b3</b>
        <c>c3</c>
    </foo>
</doc>

XQuery

let $xml := doc('file:///C:/SO/so_xquery_question.xml')

return
<test>{
for $foo in $xml/doc/foo
order by $foo/c, $foo/b descending
return
    $foo
}</test>

输出

<test>
   <foo id="foo2">
        <a>a2</a>
        <b>b2</b>
        <c>c0</c>
    </foo>
   <foo id="foo1">
        <a>a1</a>
        <b>b1</b>
        <c>c0</c>
    </foo>
   <foo id="foo3">
        <a>a3</a>
        <b>b3</b>
        <c>c3</c>
    </foo>
</test>

输出排序正确;首先是 c(升序),然后是 b(降序)。

我最近的尝试部分奏效了。 (在 Saxon 和 marklogic 中。由于某些未知原因 (!@#$),它在 eXist 中的工作方式不同。)

这里是:

XQuery

let $orderby := ('c','b descending')
let $xml := doc('file:///C:/SO/so_xquery_question.xml')

return
<test>{
for $foo in $xml/doc/foo
order by
    if ($orderby='b') then $foo/b else (),
    if ($orderby='b descending') then $foo/b else () descending,
    if ($orderby='c') then $foo/c else (),
    if ($orderby='c descending') then $foo/c else () descending
    return
        $foo
}</test>

输出

<test>
   <foo id="foo3">
        <a>a3</a>
        <b>b3</b>
        <c>c3</c>
    </foo>
   <foo id="foo2">
        <a>a2</a>
        <b>b2</b>
        <c>c0</c>
    </foo>
   <foo id="foo1">
        <a>a1</a>
        <b>b1</b>
        <c>c0</c>
    </foo>
</test>

如您所见,它首先在 b 上排序(降序)。这是因为这是 order by 中的 if 语句的顺序;不在变量序列 ($orderby) 的顺序上。如果我交换 if 的顺序(首先测试 c),它排序很好。

我在 eXist 中也有这个工作,但它不处理 descending:

order by util:eval(concat('$foo/',string-join(tokenize($orderby,'\s')[1],', $foo/')))

有什么方法可以进行考虑以下因素的动态排序?

  • 可以将要排序的元素名称作为变量传递。
  • 可以为变量中的元素名称指定可选的“降序”。
  • 维护变量的顺序(主要排序与次要排序)。

最佳答案

这是 XQuery 1.0 中的一个漏洞,我认为 3.0 没有修复它。

对于非评估方法,你试过这样的方法吗?

if ($orderby='b') then $foo/b
else if ($orderby='c') then $foo/c else (),
if ($orderby='b descending') then $foo/b
else if ($orderby='c descending') then $foo/c else () descending

但是我可能会将键和方向分成两个不同的变量。

关于xml - XQuery 中基于变量的动态排序(排序依据),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23769228/

相关文章:

java - 使用 java 对输入 XML 进行 XSL 转换

xml - 如何在生成 XML 时省略 GO 中的空字段

python - 避免 Python 循环时出现索引错误

xquery - XQueryX 的任何实现?

sql - 除了结构化 XML 数据之外,还选择行数据

android - 开关按钮拇指歪斜?

android - 更改搜索栏颜色

algorithm - 如何按字典顺序对数字进行排序?

sorting - 如何在谷歌图表中将首次点击排序设置为降序

sql - 使用 XQUERY/Modify 将我的一段 XML 替换为来自 varchar 字段的值