xml – 基于变量的动态排序(order by),在XQuery中
|
我正在尝试在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上进行排序(降序).这是因为这是顺序中if语句的顺序;不是变量序列的顺序($orderby).如果我交换ifs的顺序(首先测试c),它排序很好. 我也有这个工作在eXist,但它不处理下降: order by util:eval(concat('$foo/',string-join(tokenize($orderby,'s')[1],',$foo/')))
我有什么方法可以进行动态排序,并考虑以下因素? >可以传递元素名称作为变量排序.
这是XQuery 1.0中的一个漏洞,我认为3.0没有修复它.
对于非eval方法,你尝试过类似的东西吗? 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 但是我可能会将键和方向分成两个不同的变量. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
