MarkLogic Xquery:如何在 for 循环中对字符串值进行排序

MarkLogic Xquery: How to sort string values in a for loop

我有一个序列需要根据最早年份和最近年份对列表进行排序。由于年份元素中有一些独特的值,这使得排序变得有点复杂。有什么办法可以达到以下目的吗?

let $dates := ('1982', '2019', '2095', 'pre-1982', 'post-2095')
return    
for $date in $dates
order by $date
return $date

日期元素文本通常是数据中的年份,但离群值案例有一个前置或 post- 附加。有什么方法可以最低限度地实现这一点?

我不确定这是否是最小的,但它有效:

let $dates := ('1982', '2019', '2095', 'pre-1982', 'post-2095')
return    
for $date in $dates
let $year := 
        if (fn:contains($date, "-")) 
        then fn:substring-after($date, "-") 
        else $date

let $prepost := 
        if (fn:starts-with($date, "pre")) 
        then -1 
        else if (fn:starts-with($date, "post")) 
        then 1
        else 0
order by $year, $prepost
return $date

仅供参考:绝对不是最小的,但我想知道返回序列时 fn:sort 做了什么。事实证明它做对了。

xquery version "3.1";

declare variable $local:ascending := 1;
declare variable $local:descending := -1;

declare function local:sort-prefixed-years ($y, $order) {
    if (fn:contains($y, "-")) 
    then (
        let $p := fn:tokenize($y, "-")
        let $m :=
            switch($p[1])
            case "pre" return -1 * $order
            case "post" return 1 * $order
            default return 0
        return (xs:integer($p[2]) * $order, $m)
    )
    else (xs:integer($y) * $order, 0)
};

declare function local:sort-prefixed-years-ascending ($prefixed-year) {
    local:sort-prefixed-years($prefixed-year, $local:ascending)
};

declare function local:sort-prefixed-years-descending ($prefixed-year) {
    local:sort-prefixed-years($prefixed-year, $local:descending)
};

let $dates := ('1982', '2019', '2095', 'pre-1982', 'post-2095')
return sort($dates, (), local:sort-prefixed-years-descending#1)