参考来源:《XML 路径语言(XPath) (版本 1.0)》
地址路径
未经缩写的句法的地址路径的一些例子:
- child::para 选择上下文节点的所有子节点中名为 para 的子元素
- child::* 选择上下文节点的所有子元素
- child::text() 选择上下文节点的子节点类型为文本的所有文本节点
- child::node() 选择上下文节点的所有的孩子,而不论它们是什么节点类型
- attribute::name 选择上下文节点所有属性中名为 name 的属性
- attribute::* 选择上下文节点的所有属性
- descendant::para 选择上下文节点的所有子孙中名为 para 的元素
- ancestor::div 选择上下文节点的所有祖先中名为 div 的元素
- ancestor-or-self::div 选择上下文节点的所有祖先中名为 div 的祖先元素,并且,如果上下文节点为 div 元素,则该上下文节点也被选择
- descendant-or-self::para 选择上下文节点的所有子孙节点中名为 para 的子孙元素,而且,如果上下文节点是一个 para 元素,则该上下文节点也被选择
- self::para 如果上下文节点是一个名为 para 的元素,选择该上下文节点,否则不选择任何东西
- child::chapter/descendant::para 选择上下文节点的所有子节点中名为 chapter 的子元素的所有子节点中名为 para 的子元素
- child::*/child::para 选择上下文节点的所有名为 para 孙元素
- / 选择文档根(它总是是文档元素的父)
- /descendant::para 选择在同一文档中所有的 para 元素作为上下文节点
- /descendant::olist/child::item 选择在同一文档中所有的以 olist 为父的 item 元素作为上下文节点
- child::para[position()=1] 选择上下文节点的第一个 para 孩子
- child::para[position()=last()] 选择上下文节点的最后一个 para 孩子
- child::para[position()=last()-1] 选择上下文节点的倒数第二个 para 孩子
- child::para[position()>1] 选择上下文节点中除第一个以外所有的 para 孩子
- following-sibling::chapter[position()=1] 选择上下文节点的下一个 chapter 兄弟
- preceding-sibling::chapter[position()=1] 选择上下文节点的前一个 chapter 兄弟
- /descendant::figure[position()=42] 选择文档中第四十二个 figure 元素
- /child::doc/child::chapter[position()=5]/child::section[position()=2] 选择文档元素 doc 的第五个 chapter 的第二个 section
- child::para[attribute::type='warning"] 选择的上下文节点中有属性 type 且值为 warning 的 para 孩子
- child::para[attribute::type='warning'][position()=5] 选择的上下文节点中所有的有属性 type 且值为 warning 的 para 孩子中第五个孩子
- child::para[position()=5][attribute::type="warning"] 选择的上下文节点中第五个 para 孩子,如果该孩子有 type 属性且值为 warning 的话
- child::chapter[child::title='Introduction'] 选择的上下文节点的 chapter 孩子,这些孩子有一个或一个以上字串值等於 Introduction 的 title 孩子
- child::chapter[child::title] 选择的上下文节点中有一个或一个以上 title 孩子的 chapter 孩子
- child::*[self::chapter or self::appendix] 选择上下文节点的 chapter 和 appendix 孩子
- child::*[self::chapter or self::appendix][position()=last()] 选择上下文节点的最后一个 chapter 或 appendix 孩子
地点步进
一个地点步进有三个部分:
- 一个轴,它指定了地点步进选择的节点与上下文节点之间树状关系,
- 一个节点测试,它指定地点步进选择的节点的节点类型以及节点扩展名,和
- 零个或零个以上的判定词,它使用专有的表达式进一步细化地点步进选择的节点集合。
地点步进的句法是由两个冒号分开的轴名和节点测试,其后可跟随零个或零个以上在方括符内的表达式。例如,在 child::para[position()=1] 中,child 是轴名,para 是节点测试而 [position()=1] 则是判定词。
由地点步进选择的节点集合是源于从轴和节点测试产生初始的节点集合,然后再由各个判定词的依次过滤后的节点集合。
轴
以下是可用到的轴:
- child 轴包含上下文节点的孩子
- descendant 轴包含上下文节点的子孙;子孙是一个孩子或一个孩子的一个孩子,等等,这样,子孙轴从来不包含属性或命名空间节点
- parent 轴包含上下文节点的父,如果有的话
- ancestor 轴包含上下文节点的祖先;上下文节点的祖先由上下文节点的父以及父的父等等组成;这样,祖先轴将总是包括根节点,除非上下文节点是根节点
- following-sibling 轴包含上下文节点的所有在其后的兄弟,如果上下文节点是属性节点或命名空间节点,following-sibling 轴则为空
- preceding-sibling 轴包含上下文节点的所有在其前的兄弟,如果上下文节点是属性节点或命名空间节点,preceding-sibling 轴则为空
- following 轴包含在上下文节点所在的同一文档中,所有依照文档顺序在上下文节点后的节点,但排除所有的子孙,也排除属性节点以及命名空间节点
- preceding 轴包含在上下文节点所在的同一文档中,所有依照文档顺序在上下文节点前的节点,但排除所有的子孙,也排除属性节点以及命名空间节点
- attribute 轴包含上下文节点的属性,除非上下文节点是元素,该轴将为空
- namespace 轴包含上下文节点的命名空间节点,除非上下文节点是元素,该轴将为空
- self 轴只是包含上下文节点自己
- descendant-or-self 轴包含上下文节点和上下文节点的子孙
- ancestor-or-self 轴包含上下文节点和上下文节点的祖先;这样,该轴将总是包括根节点
注意:
ancestor,descendant,following,preceding 以及 self 轴划分了一个文档(忽略属性和命名空间节点):他们相互不重叠,而且他们组在一起则包含了文档所有的节点。
节点测试
[定义:每个轴都有一个基本节点类型。如果轴能包含元素,基本的节点类型则是元素;否则,它的类型是轴能包含的节点的类型。]因此,
对於属性轴来说,基本的节点类型是属性。
对於命名空间轴,基本的节点类型是命名空间。
对於其它的轴,基本的节点类型是元素。
当且仅当节点的类型(参看5 数据模型)是基本类型且扩展名等於由 QName 指定的扩展名时,为 QName 节点测试才为真。例如,child::para 选择了上下文节点的 para 元素孩子,如果上下文节点没有 para 孩子,它将选择节点的一个空集合;attribute::href 选择了上下文节点的 href 属性,如果上下文节点没有 href 属性,它将选择节点的一个空集合。
使用来自表达式的上下文的命名空间声明,在节点测试里的 QName 可扩展成扩展名。这与在起始及结束标签中元素类型名称的扩展方法一样,除了缺省的 xmlns 命名空间申明无须使用外:如果 QName 没有前缀,则命名空间 URI 为空 (这与属性名字扩展的方法一样)。如果 QName 有前缀,而表达式上下文中却没有命名空间声明,则是一个错误。
对於基本节点类型的任何节点,节点测试 * 都为真。例如,child::* 将选择上下文的所有的元素孩孩子,而 attribute::* 将选择上下文节点的所有的属性。
节点测试可以用格式 NCName:*。在这种情况下,前缀就以与 QName 一样的方法被扩展,即使用上下文命名空间声明。在表达式上下文的前缀如果没有命名空间声明,则是一个错误。不论名字的局域部分,对於基本类型的任何节点,如果其扩展名有命名空间 URI 将其前缀扩展,节点测试永为真。
对於任何正文节点,节点测试 text() 为真。例如,child::text() 将选择上下文节点的正文节点孩子。 同样,对於注释节点,节点测试 comment() 为真;对於处理指令,节点测试 processing-instruction() 为真 ; processing-instruction() 测试可以有一个字面量 Literal 的参数,在这种情况下,对於所有的处理指令,如指令名与字面量值 Literal 相等,其值为真。
对於任何节点,无论其类型,节点测试 node() 为真。
判定词
判定词依照轴过滤节点集合来生成新的节点集合。
缩简句法
这是一些使用缩简句法的地址路径例子:
- para 选择上下文节点的 para 元素孩子
- * 选择上下文节点的所有的元素孩子
- text() 选择上下文节点的所有的正文节点孩子
- @name 选择上下文节点的 name 属性
- @* 选择上下文节点的所有的属性
- para[1] 选择上下文节点的第一个 para 孩子
- para[last()] 选择上下文节点的最后一个 para 孩子
- */para 选择上下文节点的所有的 para 孙子
- /doc/chapter[5]/section[2] 选择doc的第五个 chapter 的第二个 section
- chapter//para 选择上下文节点的 chapter 元素孩子的所有 para 元素子孙
- //para 选择文档根的所有的 para 子孙,也就是选择上下文节点所在的文档中所有的 para 元素
- //olist/item 选择上下文节点所在的文档中所有的以 olist 为父的 item 元素
- . 选择上下文节点
- .//para 选择上下文节点的 para 元素子孙
- .. 选择上下文节点的父
- ../@lang 选择上下文节点的父的 lang 属性
- para[@type="warning"] 选择的上下文节点的所有的有属性 type 且值为 warning 的 para 孩子
- para[@type="warning"][5] 选择的上下文节点的所有的有属性 type 且值为 warning 的 para 孩子中的第五个
- para[5][@type="warning"] 选择的上下文节点的第五个 para 孩子如果该节点有属性 type 且值为 warning 的话
- chapter[title="Introduction"] 选择上下文节点的 chapter 孩子如果它有一个或多个 title 孩子且字串值为 Introduction
- chpater[title] 选择的上下文节点中有一个或一个以上 title 孩子的 chpater 孩子
- employee[@secretary and @assistant] 选择上下文节点的所有既有 secretary 属性又有 assistant 属性的 employee 孩子
最重要的缩写是 child:: 能从地点步进省略掉。实际效果上,child 是缺省轴。例如,地址路径 div/para 是 child::div/child::para 的缩写。
属性也有缩写形式: attribute:: 能被缩写成 @。例如,地址路径 para[@type="warning"] 为 child::para[attribute::type="warning"] 的缩写,也就是选择有 type 属性且属性值为 warning 的 para 孩子。
// 是 /descendant-or-self::node()/ 的缩写。例如,//para 是 /descendant-or-self::node()/child::para 的缩写,因此选择文档中所有的 para 元素(即使 para 元素是文档元素,也会被 //para 所选择,因为文档元素是根节点的孩子); div//para 是 div/descendant-or-self::node()/child::para 的缩写,因此将选择 div 孩子的所有 para 子孙。
注意:
地址路径 //para[1] 与地址路径 /descendant::para[1] 的含意不一样,后者选择第一个 para 元素子孙(只选中一个),前者选择是每一级别(深度)第一个 para 元素(可能有多个),如:
//BBB[1] | /descendant::BBB[1] |
<AAA > <BBB /> <CCC /> <BBB /> <BBB /> <DDD > <BBB /> </DDD > <CCC /> </AAA > | <AAA > <BBB /> <CCC /> <BBB /> <BBB /> <DDD > <BBB /> </DDD > <CCC /> </AAA > |
地点路进 . 是 self::node() 的缩写。这与 // 一起使用特别有用。例如,地址路径 .//para 是 self::node()/descendant-or-self::node()/child::para 的缩写,因此将选择上下文节点的所有的 para 子孙元素。
同样,地址路径 .. 是 parent::node() 的缩写。例如,../title 是 parent::node()/child::title 的缩写因此这将选择上下文节点的父的 title 孩子。