XML学习笔记#4:XPath
XPath即为XML路径语言(XML Path Language),这是一篇XPath的笔记。
概述
XPath的主要功能是定位XML文档中的某部分内容,换句话说,就是确定一条路,使得电脑能够顺着这条路找到你想要的节点。
语法
节点
节点是XPath中的基本单位,以下几种都属于节点:
1 | <bookstore> <!-- 文档节点 --> |
而节点中的数据被称为原子值 ,比如上述例子中,J K. Rowling与“en”都属于原子值。
而节点之间的关系 分为父(Parent)、子(Children)、兄弟(Sibling)、先辈(Ancestor)与后代(Descendant)。举个例子,在如下文档中:
1 | <bookstore> |
<title>的父节点是<book>,而先辈节点是<book>与<bookstore>;<bookstore>的子节点是<book>,而后代节点是<book>、<title>、<author>、<year>以及<price>。
基本语法
1 |
|
在以上文档中,假如我们需要匹配所有<title>元素,那就可以使用以下语法:
1 | /bookstore/book/title |
这就是XPath的最核心语法,是不是一看就懂。当然,在匹配过程中,为了方便地操作,还有一些路径表达式可以选用:
表达式 | 描述 | 实例 |
---|---|---|
nodename | 选取此节点的所有子节点。 | bookstore |
/ | 从根节点选取。 | /bookstore |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 | //title |
. | 选取当前节点。 | //title/. |
.. | 选取当前节点的父节点。 | //title/.. |
@ | 选取属性。 | //@lang |
在匹配过程中,假如我们要匹配到一些未知节点,或是不精确匹配,就可以用通配符 来匹配未知节点:
通配符 | 描述 | 实例 |
---|---|---|
* | 匹配任何元素节点。 | /bookstore/* |
@* | 匹配任何属性节点。 | //title/@* |
node() | 匹配任何类型的节点。 | //book/node() |
在匹配过程中,如果要选取若干路径,则可以用 “|” 运算符连接:
1 | //book/title | //book/price |
谓语
谓语相当于在匹配的过程中加入一些限定条件,起到过滤地作用。看几个例子就能明白了:
表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。(注意,是从1开始,而不是从0开始) |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position() < 3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang=‘eng’] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]//title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
轴
如果我们已经确定了一个节点,但要顺着这个节点匹配与它相关的其他值,那就可以通过轴来进行查找。比如我们要匹配bookstore下的所有title节点,但我们不清楚title的具体位置,就可以用如下表达式:
1 | /bookstore/descendant::title |
其中,/descendant::title即是一段轴表达式,表示匹配后代中所有的title元素,轴表达式有以下多种选择:
轴 | 结果 |
---|---|
ancestor | 选取当前节点的所有先辈(父、祖父等)。 |
ancestor-or-self | 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。 |
attribute | 选取当前节点的所有属性。 |
child | 选取当前节点的所有子元素。 |
descendant | 选取当前节点的所有后代元素(子、孙等)。 |
descendant-or-self | 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 |
following | 选取文档中当前节点的结束标签之后的所有节点。 |
following-sibling | 选取当前节点之后的所有兄弟节点 |
namespace | 选取当前节点的所有命名空间节点。 |
parent | 选取当前节点的父节点。 |
preceding | 选取文档中当前节点的开始标签之前的所有节点。 |
preceding-sibling | 选取当前节点之前的所有同级节点。 |
self | 选取当前节点。 |
节点测试函数
由于函数有很多,所以这里只稍微介绍几个:
comment()
对注释节点返回 True。如following::comment()
可以选择所有出现在上下文节点之后的注释节点。
text()
对文本节点返回 True。如child::text()
选择属于上下文节点子级的文本节点。
empty()
如果参数值是空序列则返回 True。如 //book[empty(child::title)]/price
选择所有不含title的book的price。
类型
XPath是强类型的语言。在查询计划的编写和执行过程中,数据类型扮演着重要的角色。
序列类型
这里举两个函数:
codepoints-to-string(int arg[])
该函数将序列中的数值(Unicode代码点)转换为字符串。参数 arg 是一个由0或多个整数值构成的序列,返回值是一个字符串。
如codepoints-to-string((88, 81, 117, 101, 114, 121))
返回 “XQuery”。
string-to-codepoints(string arg)
该函数将参数中的字符串转换为Unicode代码点。参数 arg 是一个空序列或者一个字符串,返回值是一个由0或多个整数值构成的序列。
如 string-to-codepoints("XQuery")
返回 (88, 81, 117, 101, 114, 121) 。
类型转换
与大多数一样,XPath也支持隐式类型转换与显式类型转换。这边介绍一下几个显式类型转换的相关操作符:
cast as
可以使用 cast as 操作符进行显式类型转换。比如,表达式 "123" cast as xs:integer
可以将字符串 123 转换为整型值。
castable as
可以使用 castable as 操作符判断是否能够成功地进行显式类型转换,但并不进行类型转换。返回值为 true 或 false。
instance of
如果输入数据是目标类型的实例,则返回 true,否则返回 false。
-
对于简单数据类型:通过限制派生的数据类型的值 instance of 原数据类型 = true
-
对于用户定义的复杂类型:通过扩展派生的数据类型的值 instance of 原数据类型 = true