版权 © 1999 W3C® (MIT, INRIA, Keio),保留所有权利。W3C 责任,商标,文档使用 和 软件许可 规则适用。
XPath 是一种用于定位 XML 文档部分的语言,旨在同时被 XSLT 和 XPointer 使用。
状态更新(2016年10月): 虽然 XPath 1.0 仍被广泛使用,并且在其他 W3C 规范中被规范性引用,但建议读者注意已有后续版本,并且本文件不再进行任何维护(包括纠正已报告的错误)。有兴趣获取最新 XPath 规范的读者请参阅 https://w3org.cn/TR/xpath-3/。
本文件已由 W3C 成员和其他相关方评审,并经主任批准成为 W3C 推荐稿。它是一个稳定的文档,可作为参考材料使用或在其他文档中被引用为规范性参考。W3C 在发布推荐稿时的作用是引起对该规范的关注并促进其广泛部署。这提升了 Web 的功能性和互操作性。
本规范已知错误列表位于 https://w3org.cn/1999/11/REC-xpath-19991116-errata。
本规范的英文版本是唯一规范版本。如需本文档的译本,请参阅 https://w3org.cn/Style/XSL/translations.html。
当前 W3C 推荐标准及其他技术文档的列表可在 https://w3org.cn/TR 找到。
本规范由 XSL 工作组和 XML 链接工作组共同完成,属于 W3C 样式(Style)活动 和 W3C XML 活动的一部分。
XPath 是为在 XSL 转换 [XSLT] 和 XPointer [XPointer] 之间共享的功能提供共通语法和语义的努力成果。XPath 的主要目的是定位 XML [XML] 文档的各个部分。为实现此主要目的,XPath 还提供了对字符串、数值和布尔值的基本操作功能。XPath 使用紧凑的、非 XML 语法,以便在 URI 和 XML 属性值中使用。XPath 作用于 XML 文档的抽象逻辑结构,而非其表面语法。XPath 的名称来源于其使用类似 URL 的路径表示法来在 XML 文档的层次结构中进行导航。
除了用于定位之外,XPath 还被设计为拥有一个自然子集,可用于匹配(测试节点是否匹配某模式);此用途的 XPath 在 XSLT 中有描述。
XPath 将 XML 文档建模为节点树。节点有不同的类型,包括元素节点、属性节点和文本节点。XPath 为每种节点类型定义了一种 string-value 的计算方式。一些节点类型还有名称。XPath 完全支持 XML 命名空间 [XML Names]。因此,节点的名称被建模为由本地部分和(可能为 null 的)命名空间 URI 组成的二元组,这称为 expanded-name。数据模型的详细描述见 [5 Data Model]。
XPath 中的主要语法构造是表达式。表达式符合产生式 Expr。表达式在求值后产生一个对象,该对象属于以下四种基本类型之一:
表达式的求值是在某个上下文下进行的。XSLT 和 XPointer 分别规定了在 XSLT 和 XPointer 中使用的 XPath 表达式的上下文如何确定。上下文由以下内容组成:
上下文位置始终小于或等于上下文大小。
变量绑定是一个从变量名到变量值的映射。变量的值是一个对象,可以是表达式可能返回的任意类型,也可能包含此处未列出的其他类型。
函数库是一个从函数名到函数实现的映射。每个函数接受零个或多个参数并返回单一结果。本文件定义了所有 XPath 实现必须支持的核心函数库(见 [4 Core Function Library])。在核心函数库中的函数,其参数和结果均属于上述四种基本类型。XSLT 和 XPointer 通过定义额外函数来扩展 XPath;其中一些函数仍只操作这四种基本类型,另一些则操作 XSLT 和 XPointer 定义的附加数据类型。
命名空间声明是从前缀到命名空间 URI 的映射。
用于求值子表达式的变量绑定、函数库以及命名空间声明始终与求值包含该子表达式的父表达式时使用的相同。用于求值子表达式的上下文节点、上下文位置和上下文大小有时会与父表达式求值时使用的不同。若某类表达式会改变上下文节点,则只有谓词会改变上下文位置和上下文大小(见 [2.4 Predicates])。在描述某类表达式的求值过程时,如果上下文节点、上下文位置或上下文大小会发生变化,将会明确指出;若未提及,则在该类表达式的子表达式求值时保持不变。
XPath 表达式常出现在 XML 属性中。本节所给的语法适用于 XML 1.0 规范化后的属性值。例如,如果语法使用字符 <,则在 XML 源码中必须写成 < 以符合 XML 1.0 规则。表达式中的字面字符串用单引号或双引号界定,这与 XML 属性的界定方式相同。为防止表达式中的引号被 XML 处理器误认为属性值的结束,可使用字符引用(" 或 ')来表示引号。或者,在属性使用双引号界定时,表达式使用单引号,反之亦可。
一个重要的表达式类型是定位路径。定位路径相对于上下文节点选择一组节点。对定位路径表达式的求值结果是包含该定位路径所选节点的节点集。定位路径可以递归地包含用于过滤节点集的表达式。定位路径符合产生式 LocationPath。
在下面的语法中,非终结符 QName 与 NCName 在 [XML Names] 中定义,S 在 [XML] 中定义。语法使用与 [XML] 相同的 EBNF 记号(唯一的区别是语法符号首字母均为大写)。
表达式的解析首先把待解析的字符序列划分为记号(tokens),随后对记号序列进行语法分析。记号之间可以自由使用空白字符。记号化过程在 [3.7 Lexical Structure] 中描述。
虽然定位路径不是语言中最一般的文法构造(LocationPath 是 Expr 的一种特例),但它是最重要的构造,因此首先对其进行描述。
每个定位路径都可以用一种直接但稍显冗长的语法来表达。同时也提供了一些语法缩写,使常见情况能够简洁地表示。本节将先使用未缩写的语法解释定位路径的语义,然后通过展示其如何展开为未缩写的语法来说明缩写语法(见 [2.5 Abbreviated Syntax])。
以下是使用未缩写语法的定位路径示例:
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 子节点之外的所有 para 子节点。
following-sibling::chapter[position()=1] 选中紧随上下文节点之后的第一个 chapter 同级节点。
preceding-sibling::chapter[position()=1] 选中紧靠在上下文节点之前的第一个 chapter 同级节点。
/descendant::figure[position()=42] 选中文档中的第 42 个 figure 元素。
/child::doc/child::chapter[position()=5]/child::section[position()=2] 选中 doc 文档元素的第 5 章中的第 2 节。
child::para[attribute::type="warning"] 选中所有拥有 type 属性且属性值为 warning 的 para 子节点。
child::para[attribute::type='warning'][position()=5] 选中拥有 type 属性且属性值为 warning 的第 5 个 para 子节点。
child::para[position()=5][attribute::type="warning"] 若第 5 个 para 子节点的 type 属性值为 warning,则选中该节点。
child::chapter[child::title='Introduction'] 选中拥有一个或多个 title 子节点且其 string-value 等于 Introduction 的 chapter 子节点。
child::chapter[child::title] 选择上下文节点的 chapter 子节点,这些子节点具有一个或多个 title 子节点
child::*[self::chapter or self::appendix] 选择上下文节点的 chapter 和 appendix 子节点
child::*[self::chapter or self::appendix][position()=last()] 选中上下文节点的最后一个 chapter 或 appendix 子节点。
定位路径有两种:相对定位路径和绝对定位路径。
相对定位路径由一个或多个定位步骤组成,步骤之间使用 / 分隔。相对定位路径的步骤从左至右依次组合。每一步相对白上下文节点选择一组节点。初始步骤序列选出一组相对于当前上下文节点的节点;该集合中的每个节点随后作为下一步的上下文节点;下一步选出的节点集合再进行并集操作。最终的节点集合即为所有步骤组合后的并集。例如,child::div/child::para 选中上下文节点的 div 子节点的 para 子节点,换句话说,选中拥有 div 父节点的 para 孙子节点。
绝对定位路径由单独的 /(可选后接相对定位路径)构成。单独的 / 选中包含上下文节点的文档的根节点。如果 / 后面跟随相对定位路径,则该定位路径相对于根节点选出相应的节点集合。
| [1] | LocationPath | ::= | RelativeLocationPath | |
| | AbsoluteLocationPath | ||||
| [2] | AbsoluteLocationPath | ::= | '/' RelativeLocationPath? | |
| | AbbreviatedAbsoluteLocationPath | ||||
| [3] | RelativeLocationPath | ::= | Step | |
| | RelativeLocationPath '/' Step | ||||
| | AbbreviatedRelativeLocationPath |
定位步骤由三部分组成:
轴——指定定位步骤所选节点与上下文节点之间的树关系;
节点测试——指定定位步骤所选节点的节点类型和 expanded-name;
零个或多个谓词——使用任意表达式进一步细化定位步骤所选节点的集合。
定位步骤的语法为:轴名与节点测试之间用双冒号分隔,随后可跟随零个或多个用方括号括起的表达式。例如,在 child::para[position()=1] 中,child 为轴名,para 为节点测试,[position()=1] 为谓词。
定位步骤选中的节点集是:先根据轴和节点测试生成初始节点集,然后依次用每个谓词对该节点集进行过滤。
初始节点集由满足轴所定义的相对于上下文节点的关系且拥有节点测试所指定的节点类型和 expanded-name 的节点组成。例如,定位步骤 descendant::para 选中上下文节点的 para 后代元素节点:descendant 指定每个节点必须是上下文节点的后代,para 指定每个节点必须是名称为 para 的元素。可用的轴在 [2.2 Axes] 中描述,可用的节点测试在 [2.3 Node Tests] 中描述,某些节点测试的含义取决于所用的轴。
初始节点集先经第一个谓词过滤得到新的节点集;随后该新节点集再经第二个谓词过滤,依此类推。最终的节点集即为定位步骤选中的节点集。轴会影响每个谓词中表达式的求值方式,因此谓词的语义是相对于某个轴定义的。参见 [2.4 Predicates]。
| [4] | Step | ::= | AxisSpecifier NodeTest Predicate* | |
| | AbbreviatedStep | ||||
| [5] | AxisSpecifier | ::= | AxisName '::' | |
| | AbbreviatedAxisSpecifier |
以下轴可供使用:
the child axis contains the children of the context node
the descendant axis contains the descendants of the context node; a descendant is a child or a child of a child and so on; thus the descendant axis never contains attribute or namespace nodes
the parent axis contains the parent of the context node, if there is one
the ancestor axis contains the ancestors of the context node; the ancestors of the context node consist of the parent of context node and the parent's parent and so on; thus, the ancestor axis will always include the root node, unless the context node is the root node
the following-sibling axis contains all the following siblings of the context node; if the context node is an attribute node or namespace node, the following-sibling axis is empty
the preceding-sibling axis contains all the preceding siblings of the context node; if the context node is an attribute node or namespace node, the preceding-sibling axis is empty
the following axis contains all nodes in the same document as the context node that are after the context node in document order, excluding any descendants and excluding attribute nodes and namespace nodes
the preceding axis contains all nodes in the same document as the context node that are before the context node in document order, excluding any ancestors and excluding attribute nodes and namespace nodes
the attribute axis contains the attributes of the context node; the axis will be empty unless the context node is an element
the namespace axis contains the namespace nodes of the context node; the axis will be empty unless the context node is an element
self 轴仅包含上下文节点自身
descendant-or-self 轴包含上下文节点及其后代节点
the ancestor-or-self axis contains the context node and the ancestors of the context node; thus, the ancestor axis will always include the root node
NOTE: Theancestor,descendant,following,precedingandselfaxes partition a document (ignoring attribute and namespace nodes): they do not overlap and together they contain all the nodes in the document.
每个轴都有一个 principal node type(主要节点类型)。若一个轴能够包含元素,则其主要节点类型为元素;否则为该轴能够包含的节点类型。例如,
如果节点测试是一个 QName,则仅当节点的类型(见 [5 Data Model])为该轴的主要节点类型且其 expanded-name 与该 QName 指定的 expanded-name 相同,测试才为真。例如,child::para 选中上下文节点的 para 元素子节点;若上下文节点没有 para 子节点,则选中空集合。attribute::href 选中上下文节点的 href 属性;若不存在该属性,则选中空集合。
在节点测试中,QName 会根据表达式上下文中的命名空间声明展开为 expanded-name。这与起始和结束标签中元素类型名的展开方式相同,只是默认命名空间(xmlns)不被使用:如果 QName 没有前缀,则其命名空间 URI 为 null(这与属性名的展开方式相同)。若 QName 使用了在表达式上下文中未声明命名空间的前缀,则属于错误。
节点测试 * 对任何主要节点类型的节点均为真。例如,child::* 选中上下文节点的所有元素子节点,attribute::* 选中上下文节点的所有属性。
节点测试可以采用形式 NCName:*。此时,前缀的展开方式与 QName 相同,使用表达式上下文的命名空间声明。如果在表达式上下文中没有该前缀的命名空间声明,则为错误。该节点测试对任何主要节点类型且其 expanded-name 的命名空间 URI 与前缀展开后的 URI 相同的节点均为真,而不论本地部分为何。
节点测试 text() 对任何文本节点为真。例如,child::text() 选中上下文节点的文本子节点。类似地,comment() 对任何注释节点为真,processing-instruction() 对任何处理指令节点为真。processing-instruction() 测试可以带有一个 Literal 参数;在这种情况下,仅当处理指令的名称等于该文字值时测试为真。
节点测试 node() 对任何类型的节点均为真。
| [7] | NodeTest | ::= | NameTest | |
| | NodeType '(' ')' | ||||
| | 'processing-instruction' '(' Literal ')' |
轴要么是前向轴,要么是逆向轴。若一个轴仅包含上下文节点或在 文档顺序 中位于上下文节点之后的节点,则为前向轴。若仅包含上下文节点或在文档顺序中位于上下文节点之前的节点,则为逆向轴。因此,ancestor、ancestor-or-self、preceding、preceding-sibling 为逆向轴,其他轴均为前向轴。self 轴始终至多包含一个节点,故其前向或逆向属性没有影响。相对于某轴的节点集合成员的 proximity position(接近位置)定义为:若轴为前向轴,则该节点在文档顺序中的位置;若轴为逆向轴,则在逆文档顺序中的位置。首位为 1。
谓词对相对于某轴的节点集进行过滤,以生成新的节点集。对于待过滤的每个节点,以该节点为上下文节点、以节点集的大小为上下文大小、并以该节点相对于轴的 proximity position 为上下文位置来求值 PredicateExpr。如果 PredicateExpr 对该节点求值为 true,则该节点被包含在新节点集中;否则不包含。
PredicateExpr 的求值过程是先求值 Expr 并将结果转换为布尔值。如果结果是数值,则在数值等于上下文位置时转换为 true,否则为 false;如果结果不是数值,则按调用 boolean 函数的方式进行转换。因此,定位路径 para[3] 等价于 para[position()=3]。
| [8] | Predicate | ::= | '[' PredicateExpr ']' | |
| [9] | PredicateExpr | ::= | Expr(表达式) |
以下是使用简写语法的定位路径示例:
para 选择上下文节点的 para 元素子节点
* 选择上下文节点的所有元素子节点
text() 选择上下文节点的所有文本节点子节点
@name 选择上下文节点的 name 属性
@* 选择上下文节点的所有属性
para[1] 选择上下文节点的第一个 para 子节点
para[last()] 选中上下文节点的最后一个 para 子节点。
*/para 选择上下文节点的所有 para 孙子节点
/doc/chapter[5]/section[2] 选中 doc 文档元素的第 5 章中的第 2 节。
chapter//para 选择上下文节点的 chapter 元素子节点的 para 元素后代
//para 选中文档根节点的所有 para 后代,从而选中文档中与上下文节点同在的所有 para 元素。
//olist/item 选中同一文档中具有 olist 父节点的所有 item 元素。
. 选中上下文节点。
.//para 选择上下文节点的 para 元素后代
.. 选择上下文节点的父节点
../@lang 选择上下文节点父节点的 lang 属性
para[@type="warning"] 选择上下文节点的所有 para 子节点,这些子节点具有值为 warning 的 type 属性
para[@type="warning"][5] 选择上下文节点的第五个 para 子节点,该子节点必须具有值为 warning 的 type 属性
para[5][@type="warning"] 选择上下文节点的第五个 para 子节点,条件是该子节点具有值为 warning 的 type 属性
chapter[title="Introduction"] 选中拥有一个或多个 title 子节点且其 string-value 等于 Introduction 的 chapter 子节点。
chapter[title] 选择上下文节点的 chapter 子节点,这些子节点具有一个或多个 title 子节点
employee[@secretary and @assistant] 选择上下文节点的所有 employee 子节点,这些子节点同时具有 secretary 属性和 assistant 属性
最重要的简写是可以省略定位步骤中的 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 后代。
NOTE: The location path//para[1]does not mean the same as the location path/descendant::para[1]. The latter selects the first descendantparaelement; the former selects all descendantparaelements that are the firstparachildren of their parents.
定位步骤 . 等价于 self::node()。这在与 // 联用时特别有用。例如,定位路径 .//para 等价于
self::node()/descendant-or-self::node()/child::para
并因此选中上下文节点的所有 para 后代元素。
同理,定位步骤 .. 等价于 parent::node()。例如,../title 等价于 parent::node()/child::title,因此选中上下文节点父节点的 title 子节点。
| [10] | AbbreviatedAbsoluteLocationPath | ::= | '//' RelativeLocationPath | |
| [11] | AbbreviatedRelativeLocationPath | ::= | RelativeLocationPath '//' Step | |
| [12] | AbbreviatedStep | ::= | '.' | |
| | '..' | ||||
| [13] | AbbreviatedAxisSpecifier | ::= | '@'? |
一个 VariableReference 计算为在上下文中的变量绑定集合中该变量名所绑定的值。如果在表达式上下文的变量绑定集合中不存在该变量名的绑定,则视为错误。
可以使用圆括号进行分组。
| [14] | Expr(表达式) | ::= | OrExpr | |
| [15] | PrimaryExpr(主表达式) | ::= | VariableReference | |
| | '(' Expr ')' | ||||
| | Literal(字面量) | ||||
| | Number(数字) | ||||
| | FunctionCall(函数调用) |
一个 FunctionCall 表达式的求值过程是:使用 FunctionName 在表达式求值上下文的函数库中定位函数,对每个 Argument 进行求值,将每个参数转换为函数所要求的类型,随后调用该函数并传递已转换的参数。如果参数数量错误或某个参数无法转换为所需类型,则视为错误。FunctionCall 表达式的结果就是函数返回的结果。
一个参数会被转换为字符串类型,就像调用 string 函数一样。一个参数会被转换为数值类型,就像调用 number 函数一样。一个参数会被转换为布尔类型,就像调用 boolean 函数一样。非节点集类型的参数不能转换为节点集。
| [16] | FunctionCall | ::= | FunctionName '(' ( Argument ( ',' Argument )* )? ')' | |
| [17] | Argument(参数) | ::= | Expr(表达式) |
定位路径可以用作表达式。该表达式返回路径选中的节点集合。
`|` 运算符计算其操作数的并集,操作数必须是节点集。
`Predicate` 用于对表达式进行过滤,方式与在定位路径中使用时相同。如果待过滤的表达式求值后不是节点集,则视为错误。`Predicate` 根据子轴对节点集进行过滤。
注意:`Predicate` 的含义关键取决于所适用的轴。例如,`preceding::foo[1]` 返回按 逆文档顺序 的第一个 `foo` 元素,因为 `[1]` 谓词适用于 preceding 轴;相比之下,`(preceding::foo)[1]` 返回按 文档顺序 的第一个 `foo` 元素,因为这里的 `[1]` 谓词适用于 child 轴。
`/` 和 `//` 运算符用于组合一个表达式和相对定位路径。如果表达式求值后不是节点集,则视为错误。`/` 运算符的组合方式与在定位路径中使用 `/` 时相同。与定位路径一样,`//` 相当于 `/descendant-or-self::node()/`。
没有任何对象类型可以转换为节点集。
| [18] | UnionExpr | ::= | PathExpr | |
| | UnionExpr '|' PathExpr | ||||
| [19] | PathExpr | ::= | LocationPath | |
| | FilterExpr | ||||
| | FilterExpr '/' RelativeLocationPath | ||||
| | FilterExpr '//' RelativeLocationPath | ||||
| [20] | FilterExpr | ::= | PrimaryExpr(主表达式) | |
| | FilterExpr Predicate |
布尔类型的对象只能取两个值:true(真)和 false(假)。
`or` 表达式的求值方式是先对每个操作数求值,并像调用 `boolean` 函数一样将其值转换为布尔值。如果任一操作数为 true,则结果为 true,否则为 false。如果左操作数求值为 true,则右操作数不会被求值。
`and` 表达式的求值方式是先对每个操作数求值,并像调用 `boolean` 函数一样将其值转换为布尔值。仅当两个操作数均为 true 时结果为 true,否则为 false。如果左操作数求值为 false,则右操作数不会被求值。
`EqualityExpr`(不是单独的 `RelationalExpr`)或 `RelationalExpr`(不是单独的 `AdditiveExpr`)的求值方式是比较两个操作数求值后得到的对象。对结果对象的比较在以下三段中定义。第一,涉及节点集的比较被定义为不涉及节点集的比较的形式;对 `=`, `!=`, `<=`, `<`, `>`, `>=` 均统一如此。第二,对不涉及节点集的比较在 `=` 和 `!=` 的情况下定义。第三,对不涉及节点集的比较在 `<=`, `<`, `>=`, `>` 的情况下定义。
如果两个待比较的对象都是节点集,则当且仅当在第一个节点集中存在一个节点且在第二个节点集中存在一个节点,使得对这两个节点的 string-value 进行比较的结果为 true 时,比较结果为 true。若一个对象是节点集而另一个是数值,则当且仅当在该节点集中存在一个节点,使得将该节点的 string-value 通过 number 函数转换为数值后与待比较的数值比较得到 true 时,比较结果为 true。若一个对象是节点集而另一个是字符串,则当且仅当在该节点集中存在一个节点,使得该节点的 string-value 与该字符串比较得到 true 时,比较结果为 true。若一个对象是节点集而另一个是布尔值,则当且仅当将布尔值与通过 boolean 函数将该节点集转换为布尔值后进行比较的结果为 true 时,比较结果为 true。
当两个待比较的对象都不是节点集且运算符为 `=` 或 `!=` 时,首先将对象转换为相同的类型然后再比较:如果至少有一个对象是布尔值,则将每个对象都按 boolean 函数转换为布尔值;否则,如果至少有一个对象是数值,则按 number 函数转换为数值;否则,将两个对象都按 string 函数转换为字符串。`=` 比较在且仅在对象相等时为 true;`!=` 在且仅在对象不相等时为 true。数值比较遵循 IEEE 754 [IEEE 754] 标准。两个布尔值相等当且仅当它们都为 true 或都为 false。两个字符串相等当且仅当它们由完全相同的 UCS 字符序列组成。
注意:如果 `$x` 绑定到一个节点集,则 `$x="foo"` 的意义不同于 `not($x!="foo")`:前者在且仅在 **某个** 节点的 string-value 为 `foo` 时为 true;后者在且仅在 **所有** 节点的 string-value 为 `foo` 时为 true。
当两个待比较的对象都不是节点集且运算符为 `<=`, `<`, `>=`, `>` 时,首先将两者都转换为数值,然后按照 IEEE 754 标准比较数值。`<` 在且仅在第一个数值小于第二个数值时为 true;`<=` 在且仅在第一个数值小于或等于第二个数值时为 true;`>` 在且仅在第一个数值大于第二个数值时为 true;`>=` 在且仅在第一个数值大于或等于第二个数值时为 true。
注意: 当 XPath 表达式出现在 XML 文档中时,任何 `<` 和 `<=` 运算符必须按照 XML 1.0 规则使用实体引用(例如 `<` 和 `<=`)进行转义。下面的例子中,`test` 属性的值就是一个 XPath 表达式。<xsl:if test="@value < 10">...</xsl:if>
| [21] | OrExpr | ::= | AndExpr | |
| | OrExpr 'or' AndExpr | ||||
| [22] | AndExpr | ::= | EqualityExpr | |
| | AndExpr 'and' EqualityExpr | ||||
| [23] | EqualityExpr | ::= | RelationalExpr | |
| | EqualityExpr '=' RelationalExpr | ||||
| | EqualityExpr '!=' RelationalExpr | ||||
| [24] | RelationalExpr | ::= | AdditiveExpr(加法表达式) | |
| | RelationalExpr '<' AdditiveExpr | ||||
| | RelationalExpr '>' AdditiveExpr | ||||
| | RelationalExpr '<=' AdditiveExpr | ||||
| | RelationalExpr '>=' AdditiveExpr |
注意:上述文法的效果是运算符优先级从低到高排列(最低优先级在前)。并且所有运算符都是左结合的。例如,`3 > 2 > 1` 等价于 `(3 > 2) > 1`,其结果为 false。
或者
以及
=,!=
<=,<,>=,>
数值表示浮点数。数值可以是任意符合 IEEE 754 双精度 64 位格式的值 [IEEE 754],包括特殊的 “Not-a-Number”(NaN) 值、正负无穷大以及正负零。有关 IEEE 754 标准关键规则的概述,请参见 JLS 第 4.2.3 节。
数值运算符会先将其操作数按调用 number 函数的方式转换为数值。
`+` 运算符执行加法。
`-` 运算符执行减法。
注意:由于 XML 允许在名称中出现 `-`,所以 `-` 运算符通常需要前后有空格。例如,`foo-bar` 求值为包含名为 `foo-bar` 的子元素的节点集;`foo - bar` 求值为将第一个 `foo` 子元素的 string-value 转换为数值后减去第一个 `bar` 子元素的 string-value 转换得到的数值的差。
`div` 运算符执行符合 IEEE 754 标准的浮点除法。
`mod` 运算符返回截断除法的余数。例如,
5 mod 2 返回 1
5 mod -2 返回 1
-5 mod 2 返回 -1
-5 mod -2 返回 -1
注意:这与 Java 与 ECMAScript 中的 `%` 运算符相同。
注意:这并不等同于 IEEE 754 的 remainder 操作,后者返回四舍五入除法的余数。
| [25] | AdditiveExpr(加法表达式) | ::= | MultiplicativeExpr(乘法表达式) | |
| | AdditiveExpr '+' MultiplicativeExpr | ||||
| | AdditiveExpr '-' MultiplicativeExpr | ||||
| [26] | MultiplicativeExpr(乘法表达式) | ::= | UnaryExpr(一元表达式) | |
| | MultiplicativeExpr MultiplyOperator UnaryExpr | ||||
| | MultiplicativeExpr 'div' UnaryExpr | ||||
| | MultiplicativeExpr 'mod' UnaryExpr | ||||
| [27] | UnaryExpr(一元表达式) | ::= | UnionExpr | |
| | '-' UnaryExpr |
字符串由零个或多个字符序列组成,字符的定义遵循 XML 推荐 [XML]。在 XPath 中,单个字符对应于单个 Unicode 抽象字符及其唯一的 Unicode 标量值(参见 [Unicode]),这并不等同于 16 位的 Unicode 代码值:当抽象字符的 Unicode 标量值大于 U+FFFF 时,其编码由一对 16 位的 Unicode 代码值(代理对)组成。许多编程语言将字符串表示为一串 16 位的 Unicode 代码值;在这些语言中实现 XPath 时必须确保代理对被正确视为单个 XPath 字符。
注意:在 Unicode 中可能出现两个在字符序列上不同但应视为相同的字符串,例如某些重音字符可以采用预组合或分解形式。因此,除非 XPath 表达式及 XML 文档中的字符都已规范化为规范形式,否则 XPath 表达式可能返回意外结果。参见 [Character Model]。
当进行标记化时,总是返回最长的可能标记。
为了可读性,尽管文法中未显式允许,表达式中仍可使用空白字符:ExprWhitespace 可以在任何 ExprToken 前后自由添加。
必须按以下顺序应用特殊的分词规则,以消除 ExprToken 文法的歧义:
如果前面有一个标记且该标记不是 `@`、`::`、`(`、`[`、`,` 或 Operator 中的任意一个,则 `*` 必须被识别为 MultiplyOperator,而 NCName 必须被识别为 OperatorName。
如果一个 NCName(可能在其后有 ExprWhitespace)后紧跟 `(`,则该标记必须被识别为 NodeType 或 FunctionName。
如果一个 NCName(可能在其后有 ExprWhitespace)后紧跟两个字符 `::`,则该标记必须被识别为 AxisName。
否则,该标记不得被识别为 MultiplyOperator、OperatorName、NodeType、FunctionName 或 AxisName。
| [28] | ExprToken | ::= | '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::' | |
| | NameTest | ||||
| | NodeType | ||||
| | Operator(运算符) | ||||
| | FunctionName(函数名) | ||||
| | AxisName | ||||
| | Literal(字面量) | ||||
| | Number(数字) | ||||
| | VariableReference | ||||
| [29] | Literal(字面量) | ::= | '"' [^"]* '"' | |
| | "'" [^']* "'" | ||||
| [30] | Number(数字) | ::= | Digits(数字序列) ('.' Digits?)? | |
| | '.' Digits | ||||
| [31] | Digits(数字序列) | ::= | [0-9]+ | |
| [32] | 运算符 | ::= | OperatorName(运算符名称) | |
| | MultiplyOperator(乘法运算符) | ||||
| | '/' | '//' | '|' | '+' | '-' | '=' | '!=' | '<' | '<=' | '>' | '>=' | ||||
| [33] | OperatorName(运算符名称) | ::= | 'and' | 'or' | 'mod' | 'div' | |
| [34] | MultiplyOperator(乘法运算符) | ::= | '*' | |
| [35] | FunctionName(函数名) | ::= | QName - NodeType | |
| [36] | VariableReference | ::= | '$' QName | |
| [37] | NameTest | ::= | '*' | |
| | NCName ':' '*' | ||||
| | QName | ||||
| [38] | 节点类型 | ::= | 'comment' | |
| | 'text' | ||||
| | 'processing-instruction' | ||||
| | 'node' | ||||
| [39] | ExprWhitespace(表达式空格) | ::= | S |
本节描述 XPath 实现必须始终在用于求值表达式的函数库中提供的函数。
函数库中的每个函数均使用函数原型进行描述,原型给出返回类型、函数名以及参数类型。若参数类型后面带有问号,则该参数为可选;否则该参数为必需。
last 函数返回一个等于表达式求值上下文中 context size 的数值。
position 函数返回一个等于表达式求值上下文中 context position 的数值。
Function: number count(node-set)
count 函数返回参数节点集中节点的数量。
id 函数通过唯一 ID(参见 [5.2.1 Unique IDs])选择元素。当 id 的参数为节点集时,结果为对该节点集每个节点的 string-value 应用 id 后得到的结果的并集。当参数为其他类型时,先按 string 函数转换为字符串,然后将该字符串按空白分割成标记列表(空白为符合产生式 S 的任意字符序列);结果为包含与列表中任意标记的唯一 ID 相同的、与上下文节点位于同一文档中的元素的节点集。
id("foo") 选择唯一 ID 为 foo 的元素。
id("foo")/child::para[position()=5] 选择唯一 ID 为 foo 的元素的第五个 para 子元素。
Function: string local-name(node-set?)
local-name 函数返回参数节点集中按 文档顺序 第一个节点的 expanded-name 的本地部分。如果参数节点集为空或第一个节点没有 expanded-name,则返回空字符串。如果省略参数,则默认使用仅包含上下文节点的节点集。
Function: string namespace-uri(node-set?)
namespace-uri 函数返回参数节点集中按 文档顺序 第一个节点的 expanded-name 的命名空间 URI。如果参数节点集为空、首节点没有 expanded-name,或者该 expanded-name 的命名空间 URI 为 null,则返回空字符串。如果省略参数,则默认使用仅包含上下文节点的节点集。
注意:`namespace-uri` 返回的字符串除元素节点和属性节点外通常为空。
Function: string name(node-set?)
name 函数返回一个 QName,该 QName 表示参数节点集中按 文档顺序 第一个节点的 expanded-name。该 QName 必须依据该节点的命名空间声明来表示其 expanded-name。通常这就是 XML 源代码中出现的 QName;如果同一命名空间在该节点上有多个前缀声明,也可能出现不同的 QName。实现可以在节点的表示中保留原始前缀信息;在这种情况下,返回的字符串始终与 XML 源中使用的 QName 相同。如果参数节点集为空或首节点没有 expanded-name,则返回空字符串。如果省略参数,则默认使用仅包含上下文节点的节点集。
注意:`name` 返回的字符串与 `local-name` 返回的字符串相同,只是在元素节点和属性节点上会包含前缀。
Function: string string(object?)
string 函数按如下方式将对象转换为字符串:
节点集被转换为字符串时,返回该节点集中按 文档顺序 第一个节点的 string-value。如果节点集为空,则返回空字符串。
数值被转换为字符串时,按如下方式处理:
布尔 false 值被转换为字符串 false。布尔 true 值被转换为字符串 true。
除四种基本类型之外的其他类型对象会根据其类型以特定方式转换为字符串。
如果省略参数,则默认使用仅包含上下文节点的节点集。
注意:`string` 函数并非用于将数值转换为供用户阅读的字符串。`format-number` 函数以及 XSLT 中的 `xsl:number` 元素提供此功能(参见 [XSLT])。
Function: string concat(string, string, string*)
concat 函数返回其参数的串联结果。
Function: boolean starts-with(string, string)
starts-with 函数在第一个字符串以第二个字符串开头时返回 true,否则返回 false。
Function: boolean contains(string, string)
contains 函数在第一个字符串包含第二个字符串时返回 true,否则返回 false。
Function: string substring-before(string, string)
substring-before 函数返回第一个字符串中在第二个字符串第一次出现之前的子串;如果第一个字符串不包含第二个字符串,则返回空字符串。例如,substring-before("1999/04/01","/") 返回 1999。
Function: string substring-after(string, string)
substring-after 函数返回第一个字符串中在第二个字符串第一次出现之后的子串;如果第一个字符串不包含第二个字符串,则返回空字符串。例如,substring-after("1999/04/01","/") 返回 04/01,而 substring-after("1999/04/01","19") 返回 99/04/01。
Function: string substring(string, number, number?)
substring 函数返回第一个参数的子串,起始位置由第二个参数指定,长度由第三个参数指定。例如,substring("12345",2,3) 返回 "234"。如果未指定第三个参数,则返回从第二个参数指定的位置一直到字符串末尾的子串,例如 substring("12345",2) 返回 "2345"。
更精确地说,字符串(参见 [3.6 Strings])中的每个字符都有一个数值位置:第一个字符的位置为 1,第二个字符的位置为 2,依此类推。
注意:这与 Java 与 ECMAScript 中的 String.substring 方法不同,后者把第一个字符的位置视为 0。
返回的子串包含所有满足以下条件的字符:字符的位置大于或等于第二参数的四舍五入值,且(如果指定了第三参数)小于第二参数四舍五入值与第三参数四舍五入值之和;上述比较和加法均遵循 IEEE 754 标准;四舍五入的行为等同于调用 round 函数。下面的例子说明了各种不寻常的情况:
substring("12345", 1.5, 2.6) 返回 "234"
substring("12345", 0, 3) 返回 "12"
substring("12345", 0 div 0, 3) 返回 ""
substring("12345", 1, 0 div 0) 返回 ""
substring("12345", -42, 1 div 0) 返回 "12345"
substring("12345", -1 div 0, 1 div 0) 返回 ""
Function: number string-length(string?)
string-length 返回字符串中的字符数(参见 [3.6 Strings])。如果省略参数,则默认使用上下文节点转换为的字符串,即上下文节点的 string-value。
Function: string normalize-space(string?)
normalize-space 函数返回参数字符串,先去除前后空白并将连续的空白字符序列替换为单个空格。空白字符与 XML 中 S 产生式允许的字符相同。如果省略参数,则默认使用上下文节点转换为的字符串,即上下文节点的 string-value。
Function: string translate(string, string, string)
translate 函数返回第一个参数字符串,其中第二个参数字符串中的字符出现时会被第三个参数字符串中对应位置的字符替换。例如,translate("bar","abc","ABC") 返回 BAr。如果第二个参数字符串中存在而第三个参数字符串中对应位置没有字符(因为第二个参数更长),则会删除第一个参数中该字符的所有出现。例如,translate("--aaa--","abc-","ABC") 返回 "AAA"。如果第二个参数中同一字符出现多次,则以第一次出现的位置决定替换字符。若第三个参数比第二个参数长,超出的字符会被忽略。
注意:`translate` 并非在所有语言环境下实现大小写转换的充分方案。XPath 将来的版本可能会提供额外的大小写转换函数。
Function: boolean boolean(object)
boolean 函数按如下方式将其参数转换为布尔值:
数值为 true 当且仅当它既不是正零、负零,也不是 NaN。
节点集为 true 当且仅当它非空。
字符串为 true 当且仅当其长度非零。
除四种基本类型外的其他类型对象会根据其类型以特定方式转换为布尔值。
Function: boolean not(boolean)
not 函数在其参数为 false 时返回 true,反之返回 false。
true 函数返回 true。
false 函数返回 false。
Function: boolean lang(string)
lang 函数根据上下文节点的 xml:lang 属性声明的语言是否与参数字符串相同或为其子语言来返回 true 或 false。上下文节点的语言由其自身的 xml:lang 属性值决定;如果该节点没有此属性,则取最近具有 xml:lang 属性的祖先的属性值。如果不存在此属性,则 lang 返回 false。如果属性值等于参数(忽略大小写),或属性值在以 - 为前缀的后缀之前等于参数(同样忽略大小写),则返回 true。例如,`lang("en")` 在上下文节点为以下任意五个元素时返回 true。
<para xml:lang="en"/> <div xml:lang="en"><para/></div> <para xml:lang="EN"/> <para xml:lang="en-us"/>
Function: number number(object?)
number 函数按如下方式将其参数转换为数值:
a string that consists of optional whitespace followed by an optional minus sign followed by a Number followed by whitespace is converted to the IEEE 754 number that is nearest (according to the IEEE 754 round-to-nearest rule) to the mathematical value represented by the string; any other string is converted to NaN
boolean true is converted to 1; boolean false is converted to 0
a node-set is first converted to a string as if by a call to the string function and then converted in the same way as a string argument
an object of a type other than the four basic types is converted to a number in a way that is dependent on that type
如果省略参数,则默认使用仅包含上下文节点的节点集。
注意:The number function should not be used for conversion of numeric data occurring in an element in an XML document unless the element is of a type that represents numeric data in a language-neutral format (which would typically be transformed into a language-specific format for presentation to a user). In addition, the number function cannot be used unless the language-neutral format used by the element is consistent with the XPath syntax for a Number.
The sum function returns the sum, for each node in the argument node-set, of the result of converting the string-values of the node to a number.
The floor function returns the largest (closest to positive infinity) number that is not greater than the argument and that is an integer.
The ceiling function returns the smallest (closest to negative infinity) number that is not less than the argument and that is an integer.
The round function returns the number that is closest to the argument and that is an integer. If there are two such numbers, then the one that is closest to positive infinity is returned. If the argument is NaN, then NaN is returned. If the argument is positive infinity, then positive infinity is returned. If the argument is negative infinity, then negative infinity is returned. If the argument is positive zero, then positive zero is returned. If the argument is negative zero, then negative zero is returned. If the argument is less than zero, but greater than or equal to -0.5, then negative zero is returned.
注意:For these last two cases, the result of calling the round function is not the same as the result of adding 0.5 and then calling the floor function.
XPath 将 XML 文档视为树结构进行操作。本节描述 XPath 如何将 XML 文档建模为树。此模型仅为概念模型,并不要求任何特定实现。该模型与 XML 信息集 [XML Infoset] 的关系在 [B XML 信息集映射] 中进行说明。
XPath 操作的 XML 文档必须符合 XML 命名空间推荐 [XML Names]。
The tree contains nodes. There are seven types of node
根节点
元素节点
文本节点
属性节点
命名空间节点
处理指令节点
注释节点
For every type of node, there is a way of determining a string-value for a node of that type. For some types of node, the string-value is part of the node; for other types of node, the string-value is computed from the string-value of descendant nodes.
注意:For element nodes and root nodes, the string-value of a node is not the same as the string returned by the DOM nodeValue method (see [DOM]).
Some types of node also have an expanded-name, which is a pair consisting of a local part and a namespace URI. The local part is a string. The namespace URI is either null or a string. The namespace URI specified in the XML document can be a URI reference as defined in [RFC2396]; this means it can have a fragment identifier and can be relative. A relative URI should be resolved into an absolute URI during namespace processing: the namespace URIs of expanded-names of nodes in the data model should be absolute. Two expanded-names are equal if they have the same local part, and either both have a null namespace URI or both have non-null namespace URIs that are equal.
There is an ordering, document order, defined on all the nodes in the document corresponding to the order in which the first character of the XML representation of each node occurs in the XML representation of the document after expansion of general entities. Thus, the root node will be the first node. Element nodes occur before their children. Thus, document order orders element nodes in order of the occurrence of their start-tag in the XML (after expansion of entities). The attribute nodes and namespace nodes of an element occur before the children of the element. The namespace nodes are defined to occur before the attribute nodes. The relative order of namespace nodes is implementation-dependent. The relative order of attribute nodes is implementation-dependent. Reverse document order is the reverse of document order.
Root nodes and element nodes have an ordered list of child nodes. Nodes never share children: if one node is not the same node as another node, then none of the children of the one node will be the same node as any of the children of another node. Every node other than the root node has exactly one parent, which is either an element node or the root node. A root node or an element node is the parent of each of its child nodes. The descendants of a node are the children of the node and the descendants of the children of the node.
The root node is the root of the tree. A root node does not occur except as the root of the tree. The element node for the document element is a child of the root node. The root node also has as children processing instruction and comment nodes for processing instructions and comments that occur in the prolog and after the end of the document element.
The string-value of the root node is the concatenation of the string-values of all text node descendants of the root node in document order.
The root node does not have an expanded-name.
There is an element node for every element in the document. An element node has an expanded-name computed by expanding the QName of the element specified in the tag in accordance with the XML Namespaces Recommendation [XML Names]. The namespace URI of the element's expanded-name will be null if the QName has no prefix and there is no applicable default namespace.
注意:In the notation of Appendix A.3 of [XML Names], the local part of the expanded-name corresponds to thetypeattribute of theExpETypeelement; the namespace URI of the expanded-name corresponds to thensattribute of theExpETypeelement, and is null if thensattribute of theExpETypeelement is omitted.
The children of an element node are the element nodes, comment nodes, processing instruction nodes and text nodes for its content. Entity references to both internal and external entities are expanded. Character references are resolved.
The string-value of an element node is the concatenation of the string-values of all text node descendants of the element node in document order.
An element node may have a unique identifier (ID). This is the value of the attribute that is declared in the DTD as type ID. No two elements in a document may have the same unique ID. If an XML processor reports two elements in a document as having the same unique ID (which is possible only if the document is invalid) then the second element in document order must be treated as not having a unique ID.
注意:If a document does not have a DTD, then no element in the document will have a unique ID.
Each element node has an associated set of attribute nodes; the element is the parent of each of these attribute nodes; however, an attribute node is not a child of its parent element.
注意:This is different from the DOM, which does not treat the element bearing an attribute as the parent of the attribute (see [DOM]).
Elements never share attribute nodes: if one element node is not the same node as another element node, then none of the attribute nodes of the one element node will be the same node as the attribute nodes of another element node.
注意:The=operator tests whether two nodes have the same value, not whether they are the same node. Thus attributes of two different elements may compare as equal using=, even though they are not the same node.
A defaulted attribute is treated the same as a specified attribute. If an attribute was declared for the element type in the DTD, but the default was declared as #IMPLIED, and the attribute was not specified on the element, then the element's attribute set does not contain a node for the attribute.
Some attributes, such as xml:lang and xml:space, have the semantics that they apply to all elements that are descendants of the element bearing the attribute, unless overridden with an instance of the same attribute on another descendant element. However, this does not affect where attribute nodes appear in the tree: an element has attribute nodes only for attributes that were explicitly specified in the start-tag or empty-element tag of that element or that were explicitly declared in the DTD with a default value.
An attribute node has an expanded-name and a string-value. The expanded-name is computed by expanding the QName specified in the tag in the XML document in accordance with the XML Namespaces Recommendation [XML Names]. The namespace URI of the attribute's name will be null if the QName of the attribute does not have a prefix.
注意:In the notation of Appendix A.3 of [XML Names], the local part of the expanded-name corresponds to thenameattribute of theExpANameelement; the namespace URI of the expanded-name corresponds to thensattribute of theExpANameelement, and is null if thensattribute of theExpANameelement is omitted.
An attribute node has a string-value. The string-value is the normalized value as specified by the XML Recommendation [XML]. An attribute whose normalized value is a zero-length string is not treated specially: it results in an attribute node whose string-value is a zero-length string.
注意:It is possible for default attributes to be declared in an external DTD or an external parameter entity. The XML Recommendation does not require an XML processor to read an external DTD or an external parameter unless it is validating. A stylesheet or other facility that assumes that the XPath tree contains default attribute values declared in an external DTD or parameter entity may not work with some non-validating XML processors.
There are no attribute nodes corresponding to attributes that declare namespaces (see [XML Names]).
Each element has an associated set of namespace nodes, one for each distinct namespace prefix that is in scope for the element (including the xml prefix, which is implicitly declared by the XML Namespaces Recommendation [XML Names]) and one for the default namespace if one is in scope for the element. The element is the parent of each of these namespace nodes; however, a namespace node is not a child of its parent element. Elements never share namespace nodes: if one element node is not the same node as another element node, then none of the namespace nodes of the one element node will be the same node as the namespace nodes of another element node. This means that an element will have a namespace node
for every attribute on the element whose name starts with xmlns:;
for every attribute on an ancestor element whose name starts xmlns: unless the element itself or a nearer ancestor redeclares the prefix;
for an xmlns attribute, if the element or some ancestor has an xmlns attribute, and the value of the xmlns attribute for the nearest such element is non-empty
注意:An attribute xmlns="" "undeclares" the default namespace (see [XML Names]).
A namespace node has an expanded-name: the local part is the namespace prefix (this is empty if the namespace node is for the default namespace); the namespace URI is always null.
The string-value of a namespace node is the namespace URI that is being bound to the namespace prefix; if it is relative, it must be resolved just like a namespace URI in an expanded-name.
There is a processing instruction node for every processing instruction, except for any processing instruction that occurs within the document type declaration.
A processing instruction has an expanded-name: the local part is the processing instruction's target; the namespace URI is null. The string-value of a processing instruction node is the part of the processing instruction following the target and any whitespace. It does not include the terminating ?>.
注意:The XML declaration is not a processing instruction. Therefore, there is no processing instruction node corresponding to the XML declaration.
There is a comment node for every comment, except for any comment that occurs within the document type declaration.
The string-value of comment is the content of the comment not including the opening