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 但是我可能会将键和方向分成两个不同的变量. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |