XPath 实现必须包含这里的所有函数。
函数库中的每一个函数都有一个函数原型,该原型给定了函数的返回类型,函数的名称和函数的参数类型。如果参数类型后紧跟一个问号,那么该参数是可选的,否则,参数是必须的。
节点集函数 (Node Set Functions)
字符串函数 (String Functions)
布尔函数 (Boolean Functions)
数字函数 (Number Functions)
参考资料:
表达式是 XPath 的主要语法构件。表达式的结果是一个对象,该对象为如下四种基本数据类型:
节点集
节点集是无序的不重复的节点的集合。
运算符:
没有任何对象可以转变成节点集。
布尔
布尔对象可以取两个值:真或假。
运算符:
数字
数字表示浮点数,符合 IEEE 754 标准,包括特殊的“非数字” (NaN) 值,正负无穷大,和正负零。
运算符:
字符串
字符串是由零个或多个字符构成的字符序列,其中的字符是由 XML 建议书定义的。
表达式的求值与上下文 (context) 有关。上下文的组成:
变量绑定、函数库及命名空间声明对于求表达式或其子表达式的值总是一样的。上下文节点、上下文位置及大小对于求表达式或其子表达式的值则是不同的。有多种表达式可改变上下文节点,而只有判定词能改变上下文的位置和大小。在描述一种表达式的求值时,必须要明确地说明上下文节点、上下文位置和上下文的大小。如果没有关于上下文节点、上下文位置、上下文的大小的说明,那么对该表达式的求值就保持不变。
参考资料:
这里有一些使用缩略语法的定位路径的示例:
child 是缺省轴,所以 child:: 可以从定位阶中省略掉。例如,child::div/child::para 定位路径可以缩写成 div/para 。
属性轴 attribute:: 可以缩写成 @ 。例如,child::para[attribute::type="warning"] 定位路径可以缩写成 para[@type="warning"] 。
/descendant-or-self::node()/ 可以缩写成 // 。例如,/descendant-or-self::node()/child::para 定位路径可以缩写成 //para 。
注意:定位路径 //para[1] 和 /descendant::para[1] 具有不同的含义。前者选择了所有后代的第一个 para 子元素,是一个节点的集合。后者选择了第一个 para 后代节点,是一个节点。
self::node() 可以缩写成 . ,与 // 一起使用时非常有用。例如,定位路径 self::node()/descendant-or-self::node()/child::para 可以缩写成 .//para 。
相似的,parent::node() 可以缩写成 .. 。例如,定位路径 parent::node()/child::title 可以缩写成 ../title 。
参考资料:
这里有一些使用完整语法的定位路径的示例:
定位路径有两种:相对定位路径和绝对定位路径。
相对定位路径是由/分隔的一个或多个定位阶组成的,这些定位阶按从左到右的顺序组合。首个定位阶相对于上下文节点选择一个节点集合,这个节点集合中的每一个节点被作为下一个定位阶的上下文节点。单个定位阶选择的节点是联合在一起的。组合的定位阶选择的节点也是联合在一起的。例如,child::div/child::para 定位路径选择了上下文节点的所有 div 子元素的所有 para 子元素。
绝对定位路径是由/和其后的相对定位路径组成的。/选择文档根节点,如果其后跟有相对定位路径,那么它会相对于文档根节点进行选择。
参考资料:
定位阶 (location step) 由3部分组成:
定位阶的语法是由双冒号(::)分隔的轴名和节点测试再加上零个或多个判定词构成的。例如,在child::para[position()=1]中,child是轴名,para是节点测试,而[position()=1]是判定词。
定位阶选择的节点集合是由轴和节点测试选择的节点集合经过判定词依次过滤后形成的。
定位阶child::para[position()=1]选择的节点与上下文节点的树状关系是由轴child确定的即只选择孩子,节点测试(para)确定了节点类型为元素(child轴的基本节点类型),同时也确定了节点的expanded-name为para,判定词确定了节点的位置为1。所以,这个定位阶选择了上下文节点的第一个para子元素。
参考资料:
文档顺序(document order)就是各个节点的XML表示的首字符在文档的XML表示(展开了实体之后)中出现的顺序。因此,我们有根节点(root node)将会是第一个节点,元素节点(element node)的文档顺序为该元素的开始标签在文档的XML表示中出现的顺序。元素的命名空间节点和属性节点在元素的子节点前面,而命名空间节点又在属性节点的前面。规范中没有规定命名空间节点之间的顺序,也没有规定属性节点之间的顺序,这些是依赖于实现的。逆文档顺序(reserve document order)是文档顺序的反序。
轴又可以进一步的分成前向轴(forward axis)和反转轴(reserve axis)。前向轴包含依文档顺序在上下文节点之后的节点,也可以包含上下文节点。反转轴包含依文档顺序在上下文节点之前的节点,也可以包含上下文节点。因此,ancestor,ancestor-or-self,preceding和preceding-sibling为反转轴,其它的轴则为前向轴。self既可以是前向轴也可以是反转轴。因为self只包含上下文节点,因此将它作为前向轴还是反转轴没有什么差异。
邻近位置(proximity position)是用来描述与轴相关的节点集中节点的位置的。对于前向轴依文档顺序而定,位置从1开始。对于反转轴依逆文档顺序而定,位置从1开始。
图示 前向轴、反转轴和邻近位置
判定词(predicate)对与轴相关的节点集进行过滤并产生新的节点集。对于每一个节点,如果判定词表达式(PredicateExpr)返回true那么这个节点会包含到新的节点集中,否则这个节点会被排除在新的节点集之外。判定词表达式在处理节点时会将该节点作为上下文节点(context node),并会将节点集的大小作为上下文大小(context size),还会将该节点的邻近位置作为上下文位置(context position)。
判定词表达式的处理分成两步,首先会依据判定词表达式中表达式(Expr)计算出一个结果,然后再将这个结果转换成布尔(boolean)值。如果结果是一个数字(number)那么只有当这个数字的值和上下文位置相等时结果才会转换成true,否则转换成false。如果结果不是数字那么转换结果和调用布尔函数(boolean function)返回的结果一致。因此,para[3]和para[position=3]是等价的。
参考资料:
每一个轴都有一个基本节点类型(principal node type)。如果一个轴能够包含元素(element)那么该轴的基本节点类型就是元素。其它情况下,轴的基本节点类型就是轴能够包含的节点的类型。因此,有
节点测试 * 对于任何基本节点类型的节点都为true,例如,child::* 将会选择上下文节点的所有子元素节点,attribute::* 将会选择上下文节点的所有属性节点。
节点测试 QName 对于任何基本节点类型的节点仅当其名称与QName相同时为true,例如,child::para 选择上下文节点的所有para子元素,attribute::href 选择上下文节点的href属性。
节点测试 NCName:* 中的NCName应该是命名空间的前缀,否则认为发生了错误。该测试对于任何该命名空间下的基本节点类型的节点为true,例如,child::xhtml:* 将会选择上下文节点的子节点中所有xhtml命名空间下的节点(假定xhtml命名空间存在)。
节点测试 comment() 对于任何注释节点为true,例如,child::comment() 将会选择上下文节点的所有子注释节点。
节点测试 text() 对于任何文本节点为true,例如,child::text() 将会选择上下文节点的所有子文本节点。
节点测试 processing-instruction() 对于任何处理指令节点为true。这个节点测试还可以带有一个参数Literal,这种情况下只有处理指令节点的名字和Literal相同时该测试才为true。
节点测试 node() 对于任何节点为true。
参考资料:
我们以一个表格来给出XPath中有效的轴。这些轴描述了XPath数据模型中的各个节点与上下文节点(context node)的关系。
| 名称 | 描述 |
| self | 上下文节点自身 |
| parent | 上下文节点的父节点,如果存在父节点的话 |
| child | 上下文节点的所有子节点,不包括属性节点和命名空间节点 |
| ancestor | 上下文节点的父节点,祖父节点,...,直到文档根节点,文档根节点的ancestor轴为空节点集 |
| ancestor-or-self | 和ancestor相同,只是包括了上下文节点本身 |
| descendant | 上下文节点的所有子节点,孙节点,...,不包括属性节点和命名空间节点 |
| descendant-or-self | 和descendant相同,只是包括了上下文节点 |
| preceding | 上下文节点之前的所有节点,不包括祖先节点、属性节点和命名空间节点 |
| preceding-sibling | 上下文节点之前的所有兄弟节点,如果上下文节点为属性节点或命名空间节点则此轴为空 |
| following | 上下文节点之后的所有节点,不包括后代节点、属性节点和命名空间节点 |
| following-sibling | 上下文节点之后的所有兄弟节点,如果上下文节点为属性节点或命名空间节点则此轴为空 |
| namespace | 上下文节点的命名空间节点 |
| attribute | 上下文节点的所有属性节点 |
每一个轴都有一个基本节点类型(principal node type)。如果一个轴能够包含元素(element)那么该轴的基本节点类型就是元素。其它情况下,轴的基本节点类型就是轴能够包含的节点的类型。因此,有
这里的基本节点类型的概念在做节点测试(Node Tests)时还要用到,我到时会重再次提到它。
如果忽略属性和命名空间节点,那么ancestor,descendant,following,preceding以及self这5个轴切分整个XML文档。
最后用张图来加强一下对轴的印象,其中的红色线条表示元素节点,蓝色线条表示文本节点、注释节点与处理指令节点(图中没有出现)。
参考资料:
XPath操作XML文档时是将其作为一棵树来处理的。这棵树中包含 7 种类型的节点:
XPath数据模型中的每个节点(不管是什么类型)都会有一个string-value,而除了根节点(Root Node)、注释节点(Comment Nodes)和文本节点(Text Nodes)之外其它节点还会有一个expanded-name。Expanded-name被分割成local part和namespace URI,其中local part是一个string,而namespace URI是string或null。
| 节点类型 | string-value (或 value) | expanded-name | |||
| local part (或local name) | namespace URI | ||||
| root | the concatenation of the string-values of all text node descendants of the root node in document order | 无 | 无 | ||
| element | the concatenation of the string-values of all text node descendants of the element node in document order | 元素名不含前缀和冒号 | 命名空间的URI | ||
| text | the character data (always has at least one character of data) | 无 | 无 | ||
| attribute | the normalized value as specified by the XML Recommendation | 属性名不含前缀和冒号 | 命名空间的URI | ||
| namespace | the namespace URI that is being bound to the namespace prefix(this is empty if the namespace node is for the default namespace) | 命名空间前缀 | 为空 | ||
| processing instruction | the part of the processing instruction following the target and any whitespace (not include the terminating ?>) | PI的target | 为空 | ||
| comment | the content of the comment not including the opening <!-- or the closing --> | 无 | 无 | ||
| 节点类型 | 允许的子节点 | ||
| root | document element,processing instruction,comment nodes for processing instructions,comment nodes | ||
| element | element nodes, comment nodes, processing instruction nodes and text nodes | ||
| text | 无 | ||
| attribute | 无 | ||
| namespace | 无 | ||
| processing instruction | 无 | ||
| comment | 无 | ||
以上两表的内容源于 XML Path Language (XPath) Version 1.0
我们用一个示例来进一步阐明XPath数据模型(树)的构建,其中 | 表示回车换行,_ 表示空格。这里之所以这样表示是因为回车换行和空格也构成了文本节点。
<?xml version="1.0" encoding="UTF-8"?> <!-- comment --> <node xmlns="http://www.solol.org">| __<node1 name="n1">| ____<node11 name="n11">node11</node11>| ____<node12>node12</node12>| ____<node13>node13</node13>| __</node1>| __<node2 name="n2">node2</node2>| __<node3> ____<node31>node31</node31>| ____<node32>node32</node32>| __</node3>| </node>
上面XML文档的XPath数据模型如图所示,其中带有颜色的text节点是由回车换行和空格构成的:
XPath数据模型和DOM数据模型的不同点(只限于 XML Path Language (XPath) Version 1.0 中列出的):
参考资料: