我想按MarkLogic 8中的多个属性对文档进行排序,这些属性可能是也可能不是范围索引。
理想情况下,我会有一个XQuery函数,它接受一系列节点,一系列属性作为字符串进行排序,以及一系列按字符串排序的方向。
我通过xdmp:value
电话完成了此操作,请参见下文。然而,这很容易注射。是否有人能够使用xdmp:unpath
或xdmp:invoke
或完全不同的解决方案来帮助解决方案?
xquery version "1.0-ml";
declare function local:sort-dynamically(
$nodes as node()*,
$sortbys as xs:string*,
$directions as xs:string*
) as node()*
{
(: build the components for the order by string
model: order by node//property direction
:)
let $order-bys :=
for $i in 1 to count($sortbys)
return
"$node//" || $sortbys[$i] || " " || $directions[$i]
(: join the order bys, separated by comma + space :)
let $order-bys-string := fn:string-join($order-bys, ", ") || " "
(: create the eval string
model: for node in nodes
order by
node//property1 direction1, node//property2 direction2
return
node
:)
let $eval-string :=
fn:concat(
"for $node in $nodes ",
"order by ",
$order-bys-string,
"return $node"
)
(: evaluate the sort :)
return
xdmp:value(
$eval-string
)
};
let $nodes := (
xdmp:unquote('{"col1": "1", "col2": "a"}'),
xdmp:unquote('{"col1": "1", "col2": "a"}'),
xdmp:unquote('{"col1": "1", "col2": "b"}'),
xdmp:unquote('{"col1": "2", "col2": "a"}')
)
let $sortbys := ("col1", "col2")
let $directions := ("ascending", "descending")
return
local:sort-dynamically($nodes, $sortbys, $directions)
答案 0 :(得分:2)
如果你可以使用cts:search
和cts:index-order
,你会有更大的灵活性,但这似乎没有选择,因为你想传递一系列节点(可能在你的例子中构建在内存中),并且可能没有所有排序键的范围索引。
请注意,虽然cts:search
cts:order
xdmp:value
可以提供最佳排序效果。
总而言之,这给你留下了很少的选择。使用$sortbys as xs:string*
可能会被视为安全风险,但您可以通过严格的输入验证来抵消这种风险。您可以使用$sortbys as xs:QName+
,而不是使用$directions as xs:string*
。而不是$ascending as xs:boolean+
,您可以使用<svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="40px" height="40px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
...
<script type="text/javascript">
window.addEventListener('load',function(){
alert('Hi')
})
</script>
</svg>
(以及一些代码调整)。这会使代码注入不可能..
HTH!