XQuery 函数

XQuery 的函数是日常写查询时最强大、最常用的工具。下面把你真正会用到的所有函数,按“使用频率”和“场景”分类,直接上干货 + 真实例子(基于 XQuery 3.1,最实用版本)。

1. 最常用 30 个内置函数(99% 的查询都靠它们)

类别函数名真实例子(直接可复制)说明
节点操作node-name()node-name($book)QName("", "book")取节点名
name()name($book)"book"常用
local-name()local-name($book)"book"去前缀
exists()exists(//book) → true/false判断是否存在
empty()empty($book/price) → true(如果没有 price)
字符串contains()contains($title, "XQuery")
starts-with()starts-with($title, "Learning")
ends-with()ends-with($isbn, "-01")
substring()substring($isbn, 1, 10)
substring-before() / after()substring-before($email, "@")
string()string($book/price) → “49.99”(取文本值)
normalize-space()normalize-space($desc)(去首尾空格、换行变单空格)超实用
lower-case() / upper-case()lower-case($title)
concat()concat($first, " ", $last)
string-join()string-join($authors/author, ", ")多个作者拼成一行
replace()replace($phone, "\D", "") → 只留数字
matches()matches($isbn, "^\d{10}(\d{3})?$")正则
tokenize()tokenize($tags, "\s+") → (“xml”,”xquery”,”xpath”)按空格切
数值number()number("123.45") → 123.45
round() / ceiling() / floor()round($price * 0.9)
xs:decimal() / xs:integer()xs:decimal($book/price)强制类型
序列count()count(//book)
distinct-values()distinct-values(//book/@category)去重神器
index-of()index-of(("a","b","c","b"), "b") → (2,4)
reverse()reverse(//book)倒序
subsequence()subsequence(//book, 1, 10) → 前10本分页必备
insert-before()insert-before($seq, 3, <new/>)
remove()remove($authors, 2) → 删除第2个作者
日期时间current-date() / current-time() / current-dateTime(){current-dateTime()} → 2025-11-28T10:30:45Z
adjust-date-to-timezone()adjust-date-to-timezone(current-date(), xs:dayTimeDuration("PT8H"))转北京时间
format-date()format-date(current-date(), "[Y]-[M01]-[D01]") → “2025-11-28”
布尔逻辑not()not(@in-stock)
高级doc() / collection()doc("books.xml")collection("db/books?select=*.xml")加载外部文档
trace()trace($price, "价格是: ") → 调试时打印调试神器
serialize()serialize($result, <output:serialization-parameters><output:method value="json"/></output:serialization-parameters>)转 JSON

2. 自定义函数(XQuery 3.0+)

(: 声明函数 :)
declare function local:discount-price($book as element(book)) as xs:decimal {
    let $p := xs:decimal($book/price)
    return
        if ($book/@category = "SALE") then $p * 0.7
        else if ($p > 100) then $p * 0.85
        else $p * 0.95
};

(: 使用 :)
for $b in //book
return <item>{ $b/title , local:discount-price($b) }</item>

带默认参数(XQuery 3.1):

declare function local:format-price($price as xs:decimal, $currency as xs:string := "USD") {
    concat($currency, " ", $price)
};

3. 实务中最常见的函数组合(直接复制)

(: 1. 搜索标题或作者包含关键词(不区分大小写):)
let $kw := "xquery"
for $b in //book
where contains(lower-case($b/title), lower-case($kw))
   or contains(lower-case(string-join($b/author, " ")), lower-case($kw))
return $b

(: 2. 分页(第3页,每页10条):)
let $page := 3
let $size := 10
for $b in //book
order by $b/@id
return subsequence($b, ($page-1)*$size + 1, $size)

(: 3. 按类别分组统计:)
for $cat in distinct-values(//book/@category)
let $books := //book[@category = $cat]
order by count($books) descending
return <category name="{$cat}" count="{count($books)}" avg-price="{avg($books/price)}"/>

(: 4. 生成 JSON(XQuery 3.1):)
map {
  "total": count(//book),
  "items": array { //book ! map { "title": string(title), "price": number(price) } }
}

4. 不同处理器提供的额外实用函数

处理器超好用的专有函数例子
BaseXft:search()ft:search("books", "XQuery") 全文搜索
eXist-dbxmldb:size(), util:eval()
MarkLogiccts:search(), xdmp:document-insert()企业级
Saxonsaxon:serialize($node, “json”)

5. 一句话总结

  • 简单查 → 直接用 XPath + 谓语
  • 复杂逻辑、排序、分组、分页 → 必须用 FLWOR + 内置函数
  • 要复用 → 自己写函数(local: 或声明命名空间)
  • 要输出 JSON → XQuery 3.1 的 map/array 语法最香

把上面这些函数记下来,你写 XQuery 基本不会卡壳了!

有具体的 XML 数据或想要实现的效果,直接丢给我,我 10 秒给你最优写法!

文章已创建 2783

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部