XQuery 选择 和 过滤

在 XQuery 中,“选择”和“过滤”是最核心、最常用的操作。下面系统地用清晰例子告诉你怎么写,各种场景全部覆盖。

1. 基本路径选择(XPath 表达式)

(: 选择所有 book 元素 :)
/books/book

(: 选择根下第一层 bookstore 下的所有 book :)
bookstore/book

(: 选择整个文档所有 book(任意层级):)
//book

(: 选择有 title 属性的 book :)
//book[@title]

(: 选择价格小于 30 的书 :)
//book[price < 30]

2. 常用过滤(谓语 [])写法大全

需求XQuery 写法说明
第 n 个元素//book[1]第一个 book
最后 1 个元素//book[last()]最后一个
最后 3 个元素//book[position() > last()-3]倒数 3 本书
第 3 到第 8 个//book[position() >= 3 and position() <= 8]或者简写成 [position() = 3 to 8]
倒序取前 5 本reverse(//book)[position() <= 5]XQuery 3.0+
价格在 20~50 之间//book[price >= 20 and price <= 50]常见
价格排序后取最便宜的前 3 本for $b in //book order by xs:decimal($b/price) ascending return $b[position() <= 3]推荐写法
类别是 “WEB” 且有库存//book[@category=”WEB” and stock > 0]多条件 and
类别是 “WEB” 或 “XML”//book[@category=”WEB” or @category=”XML”]or 也可以写成
//book[@category = (“WEB”, “XML”)]推荐!更简洁
标题包含 “XQuery” (不区分大小写)//book[contains(lower-case(title), “xquery”)]XQuery 3.0
标题以 “Learning” 开头//book[starts-with(title, “Learning”)]
作者姓名包含 “Priscilla”//book[author[contains(., “Priscilla”)]]. 表示当前上下文节点文本
有多个作者,取至少有一个是中国作者的书//book[author = (“王磊”, “张三”, “李雷”)]
出版年份是 2020 年以后//book[year >= 2020]
没有 category 属性//book[not(@category)]
有 price 子元素但值为空//book[price and not(string(price)) ]

3. FLWOR 语句:最强大、最灵活的“选择 + 过滤”方式

(: 1. 基本 FLWOR :)
for $book in //book
where $book/price < 30
order by $book/price descending
return $book/title

(: 2. 返回自定义结构 :)
for $b in //book
where $b/@category = "WEB"
order by xs:decimal($b/price)
return
  <item>
    <title>{ $b/title/text() }</title>
    <price discount="10%">{ $b/price * 0.9 }</price>
  </item>

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

(: 4. 前 10 本最贵的书(分页常见写法):)
for $b in //book
order by xs:decimal($b/price) descending
return $b
=> subsequence(1, 10)   (: XQuery 3.1 箭头操作符,也可以用 [position()<=10] :)

4. 高级过滤技巧(实务中特别好用)

(: 模糊搜索标题包含 “xml” 或 “xquery”,不区分大小写 :)
let $keyword := "xml"
for $b in //book
where contains(lower-case($b/title), lower-case($keyword))
   or contains(lower-case($b/author), lower-case($keyword))
return $b

(: 正则匹配(XQuery 3.0+) :)
//book[matches(title, "XQuery|XPath|XML", "i")]   (: i 表示不区分大小写 :)

(: 深度过滤:取有至少一本价格 > 100 的类别的所有书 :)
let $expensive-cats := distinct-values(
//book[price > 100]/@category)
for $b in //book
where $b/@category = $expensive-cats
return $b

(: 条件返回不同结构(if 表达式):)
for $b in //book
return
  if ($b/price > 80) then
    <expensive>{ $b/title }</expensive>
  else
    <cheap>{ $b/title }</cheap>

5. 一句话总结“选”和“过滤”的最佳实践

场景推荐写法
简单选择直接 XPath://book[@category=”WEB”]
多条件、排序、分页用 FLWOR(for/let/where/order by/return)
需要分组、统计FLWOR + group by(XQuery 3.1)
性能要求高(大数据)加索引 + 避免在 where 里做类型转换
模糊搜索contains() + lower-case() 或 matches() 正则

把上面这些记熟,你写 XQuery 的“选择和过滤”就基本无敌了!

如果你贴一段具体的 XML 和你想要的结果,我可以立刻给你最优的 XQuery 写法。

文章已创建 2783

发表回复

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

相关文章

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

返回顶部