JavaScript must be enabled in order for you to view this page. However, it seems JavaScript is either disabled or not supported by your browser. To view this page, enable JavaScript by changing your browser options, then Try again! .

 
我的论坛
Google 网上论坛 Beta 版
Do Best Developer
访问此论坛

XPath的核心函数库 (XPath Core Function Library)

XPath 实现必须包含这里的所有函数。

函数库中的每一个函数都有一个函数原型,该原型给定了函数的返回类型,函数的名称和函数的参数类型。如果参数类型后紧跟一个问号,那么该参数是可选的,否则,参数是必须的。

节点集函数 (Node Set Functions)

  • Function: number last() 返回表达式求值上下文的大小
  • Function: number position() 返回表达式求值上下文的位置
  • Function: number count(node-set) 返回参数 node-set 中的节点个数
  • Function: node-set id(object) 通过 id 选择节点集合
  • Function: string local-name(node-set?) 返回依文档顺序参数节点集中的第一个节点的 expanded-name 中的 local part 部分。如果参数节点集为空,或参数节点集中的第一个节点的 expanded-name 为空,那么函数返回空字符串。如果参数被忽略,那么函数默认会使用仅包含上下文节点的节点集作为参数。
  • Function: string namespace-uri(node-set?) 返回依文档顺序参数节点集中的第一个节点的命名空间。如果参数节点集为空,或参数节点集中的第一个节点的 expanded-name 为空,或 expanded-name 的命名空间为空,那么函数返回空字符串。如果参数被忽略,那么函数默认会使用仅包含上下文节点的节点集作为参数。除了元素节点和属性节点外该函数返回空字符串。
  • Function: string name(node-set?) 返回依文档顺序参数节点集中的第一个节点的 expanded-name 。如果参数被忽略,那么函数默认会使用仅包含上下文节点的节点集作为参数。除了元素节点和属性节点外,由 name 函数返回的字符串将与 local-name 函数返回的字符串一样。

字符串函数 (String Functions)

  • Function: string string(object?) 将参数 object 对象转换成字符串。如果参数被忽略,那么函数默认会使用仅包含上下文节点的节点集作为参数。
  • Function: string concat(string, string, string*) 将参数字符串连接在一起形成一个新的字符串
  • Function: boolean starts-with(string, string) 如果第一个参数字符串以第二个参数字符串开始,那么函数返回 true ,否则返回 false 。
  • Function: boolean contains(string, string) 如果第一个参数字符串包含第二个参数字符串,那么函数返回 true ,否则返回 false 。
  • Function: string substring-before(string, string) 返回第一个参数字符串在第二个参数字符串首次出现之前的子字符串。如果第一个参数字符串不包含第二个参数则返回空字符串。
  • Function: string substring-after(string, string) 返回第一个参数字符串在第二个参数字符串首次出现之后的子字符串。如果第一个参数字符串不包含第二个参数则返回空字符串。
  • Function: string substring(string, number, number?) 取子字符串,注意字符串的位置从0开始
  • Function: number string-length(string?) 取字符串的长度,如果参数被省略则计算上下文节点的 string-value 值的长度。
  • Function: string normalize-space(string?) 规范化字符串
  • Function: string translate(string, string, string) 转换字符串

布尔函数 (Boolean Functions)

  • Function: boolean boolean(object) 将参数 object 对象转换成布尔值
  • boolean not(boolean) 将参数 boolean 去反
  • Function: boolean true() 返回 ture
  • Function: boolean false() 返回 false
  • Function: boolean lang(string) 判断上下文节点语言环境

数字函数 (Number Functions)

  • Function: number number(object?) 将参数 object 对象转换成数字。如果参数被忽略,那么函数默认会使用仅包含上下文节点的节点集作为参数。
  • Function: number sum(node-set) 将参数节点集中的每个节点的 string-value 值转换成数字然后取和
  • Function: number floor(number) 下取整
  • Function: number ceiling(number) 上取整
  • Function: number round(number) 取最接近参数值的整数

参考资料:

  1. XML Path Language (XPath) Version 1.0

XPath表达式 (XPath Expressions)

表达式是 XPath 的主要语法构件。表达式的结果是一个对象,该对象为如下四种基本数据类型:

  • 节点集 (Node-sets )
  • 布尔 (Booleans)
  • 数字 (Numbers)
  • 字符串 (Strings)

节点集

节点集是无序的不重复的节点的集合。

运算符:

  • | 操作符将两个节点集并到一起,合并后的集合必须是节点集

没有任何对象可以转变成节点集。

布尔

布尔对象可以取两个值:真或假。

运算符:

  • or 简洁或运算
  • and 简洁与运算
  • =、!=、<=、 <、>= 和 > 比较运算

数字

数字表示浮点数,符合 IEEE 754 标准,包括特殊的“非数字” (NaN) 值,正负无穷大,和正负零。

运算符:

  • + 加法
  • - 减法
  • * 乘法
  • div 除法
  • mod 取余

字符串

字符串是由零个或多个字符构成的字符序列,其中的字符是由 XML 建议书定义的。

表达式的求值与上下文 (context) 有关。上下文的组成:

  • 一个节点 (上下文节点)
  • 一个非零的正整数对 (上下文位置和上下文大小)
  • 一个变量绑定集合
  • 一个函数库
  • 一个表达式作用范围内的命名空间声明

变量绑定、函数库及命名空间声明对于求表达式或其子表达式的值总是一样的。上下文节点、上下文位置及大小对于求表达式或其子表达式的值则是不同的。有多种表达式可改变上下文节点,而只有判定词能改变上下文的位置和大小。在描述一种表达式的求值时,必须要明确地说明上下文节点、上下文位置和上下文的大小。如果没有关于上下文节点、上下文位置、上下文的大小的说明,那么对该表达式的求值就保持不变。

参考资料:

  1. XML Path Language (XPath) Version 1.0

XPath的定位路径的缩略语法 (XPath Abbreviated Syntax)

这里有一些使用缩略语法的定位路径的示例:

  • para 选择上下文节点的 para 子元素
  • * 选择上下文节点的所有子元素
  • text() 选择上下文节点的所有子文本节点
  • @name 选择上下文节点的 name 属性
  • @* 选择上下文节点的所有属性
  • para[1] 选择上下文节点的第一个 para 子元素
  • para[last()] 选择上下文节点的最后一个 para 子元素
  • */para 选择上下文节点的所有 para 孙元素 (上下文节点的子元素的子元素)
  • /doc/chapter[5]/section[2] 选择 doc 子元素的第 5 个 chapter 子元素中的第 2 个 section 子元素
  • chapter//para 选择上下文节点的 chapter 子元素的所有 para 后代元素
  • //para 选择文档根节点的所有的 para 后代元素
  • //olist/item 选择文档根节点的所有的以 olist 为父的 item 元素
  • . 选择上下文节点
  • .//para 选择上下文节点的所有 para 后代元素
  • .. 选择上下文节点的父元素
  • ../@lang 选择上下文节点的父元素的 lang 属性
  • para[@type="warning"] 选择上下文节点的所有 type 属性值为 warning 的 para 子元素
  • para[@type="warning"][5] 选择上下文节点的所有 type 属性值为 warning 的 para 子元素中的第 5 个
  • para[5][@type="warning"] 选择上下文节点的第 5 个 para 子元素,如果该元素的 type 属性值为 warning 的话
  • chapter[title="Introduction"] 选择上下文节点的具有一个或多个值为 Introduction 的 title 子元素的 chapter 子元素
  • chapter[title] 选择上下文节点的具有一个或多个 title 子元素的 chapter 子元素
  • employee[@secretary and @assistant] 选择上下文节点的具有 secretary 和 assistant 属性的 employee 子元素

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 。

参考资料:

  1. XML Path Language (XPath) Version 1.0

XPath的定位路径 (XPath Location Paths)

这里有一些使用完整语法的定位路径的示例:

  • 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 selects 如果上下文节点为 para 元素那么选择上下文节点,否则什么也不选
  • child::chapter/descendant::para 选择上下文节点的 chapter 子元素的 para 后代元素
  • child::*/child::para 选择上下文节点的所有 para 孙元素 (上下文节点的子元素的子元素)
  • / 选择文档的根元素(document root),总是文档元素 (docuent element) 的父元素
  • /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] 选择上下文节点中位置大于 1 的 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 个 chapter 子元素中的第 2 个 section 子元素
  • child::para[attribute::type="warning"] 选择上下文节点的所有 type 属性值为 warning 的 para 子元素
  • child::para[attribute::type='warning'][position()=5] 选择上下文节点的所有 type 属性值为 warning 的 para 子元素中的第 5 个
  • child::para[position()=5][attribute::type="warning"] 选择上下文节点的第 5 个 para 子元素,如果该元素的 type 属性值为 warning 的话
  • child::chapter[child::title='Introduction'] 选择上下文节点的具有一个或多个值为 Introduction 的 title 子元素的 chapter 子元素
  • 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::div/child::para 定位路径选择了上下文节点的所有 div 子元素的所有 para 子元素。

绝对定位路径是由/和其后的相对定位路径组成的。/选择文档根节点,如果其后跟有相对定位路径,那么它会相对于文档根节点进行选择。

参考资料:

  1. XML Path Language (XPath) Version 1.0

XPath的定位阶 (XPath Location Steps)

定位阶 (location step) 由3部分组成:

  • 轴(axis),指定了定位阶选择的节点和上下文节点的树状关系(tree relationship)
  • 节点测试(node test),指定了定位阶选择的节点的类型(node type)和expanded-name
  • 判定词(predicate),对定位阶选择的节点进行更进一步的选择

定位阶的语法是由双冒号(::)分隔的轴名和节点测试再加上零个或多个判定词构成的。例如,在child::para[position()=1]中,child是轴名,para是节点测试,而[position()=1]是判定词。

定位阶选择的节点集合是由轴和节点测试选择的节点集合经过判定词依次过滤后形成的。

定位阶child::para[position()=1]选择的节点与上下文节点的树状关系是由轴child确定的即只选择孩子,节点测试(para)确定了节点类型为元素(child轴的基本节点类型),同时也确定了节点的expanded-name为para,判定词确定了节点的位置为1。所以,这个定位阶选择了上下文节点的第一个para子元素。

参考资料:

  1. XML Path Language (XPath) Version 1.0

XPath的判定词 (XPath Predicates)

文档顺序(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]是等价的。

参考资料:

  1. XML Path Language (XPath) Version 1.0

XPath的节点测试 (XPath Node Tests)

每一个轴都有一个基本节点类型(principal node type)。如果一个轴能够包含元素(element)那么该轴的基本节点类型就是元素。其它情况下,轴的基本节点类型就是轴能够包含的节点的类型。因此,有

  • 属性轴(attribute axis)的基本节点类型是属性(attribute)
  • 命名空间轴(namespace axis)的基本节点类型是命名空间(namespace)
  • 其它轴的基本节点类型是元素(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。

参考资料:

  1. XML Path Language (XPath) Version 1.0

XPath的轴 (XPath Axes)

我们以一个表格来给出XPath中有效的轴。这些轴描述了XPath数据模型中的各个节点与上下文节点(context node)的关系。

XPath的轴
名称 描述
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)那么该轴的基本节点类型就是元素。其它情况下,轴的基本节点类型就是轴能够包含的节点的类型。因此,有

  • 属性轴(attribute axis)的基本节点类型是属性(attribute)
  • 命名空间轴(namespace axis)的基本节点类型是命名空间(namespace)
  • 其它轴的基本节点类型是元素(element)

这里的基本节点类型的概念在做节点测试(Node Tests)时还要用到,我到时会重再次提到它。

如果忽略属性和命名空间节点,那么ancestor,descendant,following,preceding以及self这5个轴切分整个XML文档。

最后用张图来加强一下对轴的印象,其中的红色线条表示元素节点,蓝色线条表示文本节点、注释节点与处理指令节点(图中没有出现)。

XPath的轴

参考资料:

  1. XML Path Language (XPath) Version 1.0

XPath的数据模型 (XPath Data Model)

XPath操作XML文档时是将其作为一棵树来处理的。这棵树中包含 7 种类型的节点:

  • root nodes
  • element nodes
  • text nodes
  • attribute nodes
  • namespace nodes
  • processing instruction nodes
  • comment nodes

XPath数据模型中的每个节点(不管是什么类型)都会有一个string-value,而除了根节点(Root Node)、注释节点(Comment Nodes)和文本节点(Text Nodes)之外其它节点还会有一个expanded-name。Expanded-name被分割成local part和namespace URI,其中local part是一个string,而namespace URI是string或null。

XPath数据模型中 7 种类型节点的string-value和expanded-name的取值规则
节点类型 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 -->

XPath数据模型中 7 种类型节点各自所允许的子节点
节点类型 允许的子节点
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节点是由回车换行和空格构成的:

XML文档的XPath数据模型

XPath数据模型和DOM数据模型的不同点(只限于 XML Path Language (XPath) Version 1.0 中列出的):

  • 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.
  • This is different from the DOM, which does not treat the element bearing an attribute as the parent of the attribute

参考资料:

  1. XML Path Language (XPath) Version 1.0
  2. Extensible Markup Language (XML) 1.0 (Third Edition)

简单,简单,在简单

我要对solol.org进行改版了。

因为经过近一年的观察,我觉得:

  • solol.org的部分页面没有什么使用价值,这些页面将会逐渐的被裁减掉。
  • solol.org的页面生成引擎中有一些功能不是很实用,这些功能将会逐渐的被删除,同时那些常用的功能将被增强。
  • solol.org的层次太多不利于内容的浏览,以后的内容将会尽力限制在三层之内。

简而言之一句话,就是简单,简单,在简单,但绝不会牺牲内容的质量。