没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
XPath 2.0 简介
两年之前,本专栏开始第一次连载时,我曾撰写过有关 版本 的文章(请参阅
以快速回顾)。正如最初的规范中所述:是一种用于
寻址 文档内容的语言。”通过使用 表达式,开发人员可以轻而易举地标识出 文档中的
节点,以进行进一步的处理。这使得利用简单的声明表达式替换复杂的遍历算法成为可能。例如,以下表
达式将标识出所有为 根元素子代且 属性值为 !"的 #元素的子元素:
$$$#%& '(!"()$*
利用传统的 编写同样的逻辑,将是一项冗长乏味且充满艰辛的工作。因此,通常会被
作为如今各种 实现(如 +,和 -等等)中的层次服务而受到支持:
$$./+,.
#-'
-01$$$#%& '(!"()$*123
0'34. 35526
$$7
8
还经常用于 中,以寻址输入文档,如下所示:
4977:;#7
'1$$$#%& '(!"()$*1$<
总体上来说,对于 开发人员而言非常重要,并迅速成为他们编程工具包中不可或缺的一部
分。本专栏的其余部分假设读者熟悉 (请参阅 7$$"$=$97)。
限制
尽管 简化了许多一般的编程任务,但是,开发人员开始想要得到更多好处。规范
在几个领域中受到了限制或混淆,需要进行一番整改。开发人员一直致力于改进 >".,并向该语言添加
了一些更为有意义的功能,其中多数功能支持对 >".规范的其他引申(如 架构、
? :以及 !)。
自从 发布以来,架构就成为 >".推荐项之一,并讯速定位为其他数个进行中的工作
的“官方”类型系统,例如 ? :和其他与 >@服务有关的工作。因为 架构是 全局中不可
或缺的组成部分,所以 >".强烈希望实现类型化 (能够选择类型 @的所有元素不是非常
好吗?)。而且,最近有关 ? :和 !的工作揭示了大量的共同基础,即两种语言在其
中均可以共享相同的数据模型和表达式语法的领域。这个最小公分母就变成了 !。
!
有关 !07$$"$=$!2的工作很好地修复了 中的问题并达到
了下列要求(位于 7$$"$=$97!A的 !=A #文
档中对此进行了概述):
B
应当保持向后兼容性
B
必须提升易用性
B
必须改善字符串操纵和匹配
B
必须支持 系列标准(!和 ? :
)
B
必须支持 架构(简单类型和复杂类型)
并不绝对要求向后兼容性的原因在于,它不如可能会形成阻碍的其他要求重要,虽然 >".已经尽全力来
全面达到该要求。
提升易用性和简化常见用例(例如使用字符串)是非常清楚的目标,但是最后两个要求带来了更为明显的
变化。在本专栏的剩余部分中,我将重点介绍这一更为显著的方面,以帮助您对即将到来的事物作好准备。
如果您在阅读本专栏时,希望试验某些示例表达式,请下载 C:的 ,-D!处理
器,该处理器包含了一个相当完整的参考实现(请参阅 7$$9 $9D!$),
除了没有包含完整的 架构支持。截至本文撰写之日止,任何 处理器(或 )
均不支持 !,但是预计它们的 ? :和 !实现支持它。虽然没有确定特定的发
布日期,但是将其与该规范的发布之日(或许会在来年)相结合会比较有意义。
一个控制所有的数据模型
可在 !的数据模型中找到其最具意义的变化。可在 ? :和 !数据模型规范
中找到 !数据模型的详细信息,而且,该信息由 !、!和 ? :共享。
!数据模型基于具备支持 架构的必要扩展的 。该数据模型定义了七个构成
文档结构的节点类型:文档(根)、元素、文本、属性、命名空间、处理指令以及注释节点。
这些节点类型类似于 数据模型中的节点类型,但是,元素和属性类型已受到扩展,以在验证
出现后包括 架构类型信息。因此产生的“类型化”数据模型被引用为后架构验证 0E2。
除基本的节点类型外,还定义了四个原子类型,以协助处理在元素和属性中发现的文本值:
节点集、字符串、数字以及布尔值。这个简单的类型系统使得在必要时,可以将文本值作为特定类型来处
理。例如,您应该考虑以下价格元素版本:
47<4$7<
47<4$7<
47<4$7<
在纯文本环境中测试特定值非常麻烦,因为您必须检查所有可能的词法格式:
7'((FF7'((FF7'((
但是,如果配备了数值类型,您就可以使用以下表达式以自动将文本强制转换为数值:
#@072'
这样可使您无需处理文档中可能用到的各种词法格式。
在 !中,原子类型系统基于该同一原则,但是它已受到扩展,以包含所有在 架构数据类
型规范中定义的数据类型(请参阅 7$$"$=$9##;!$)。图 显示了 架
构数据类型层次结构,其中的派生通过限制出现。除有 G种基元数据类型和更多的派生类型外,
!还定义了两个新的持续时间子类型,即 :+ 和 :#+ ,以简化持续
时间值的使用。所有这些类型都可以在 !中使用。
和以往一样,!类型系统可以使开发人员避免遇到过多的词法细节,允许他们主要处理值空间,
但是从现在开始,有更多的值空间需要进行选择。您可以通过数据函数访问节点的类型化值,并可以利用
? :和 !函数和运算符规范中定义的各种构造函数来构造类型化值(或 值)。
例如,以下表达式测试了是否任何 @元素的值(或其中 9被绑定至架构命名空间的类型
9)都表示 GD!年 月 日之前的日期:
0@2490(GD!;;(2
除能够使用强类型化值外,E可以使您采用任何元素或属性以及在运行时访问其类型信息,正如今天
您可以访问基本名称信息一般。可将元素绑定至简单类型或复杂类型,而始终将属性绑定至简单类型。有
几个新的利于类型检查和强制的运算符:、和 。
运算符 可以用于验证操作数是否为特定类型,如下面的相应表达式所示:
#$02%#:79 @)
#$*%9 @)
该表达式将标识出类型为 9 @的 #元素的所有子元素。运算符 可以将一种数
据类型显式转换为另一种数据类型。该运算符也许不能用于用户定义的类型。另一方面,运算符
也许可以用于用户定义的类型,以检查提供表达式的值是否是提供数据类型的实例。如果是,则
表达式会返回该表达式的值,否则它会生成一个错误。通常用于保证某值的动态类型是该值
的静态类型的特定子类型。? :和 !函数和运算符规范为类型间的强制转换定义了许
多的强制规则。这或许是该规范中最为复杂和令人不知所措的部分。
在数据模型中,另一个主要更改针对节点集或节点集不足的地方。在 中,某些表达式返回节
点集,而另一些返回原子值。在 !中,返回的就全是序列了。
序列
序列,顾名思义:就是一个包含零或包含多个项的排序系列。一个项目可能是一个原子值,或七个节点类
型之一。在将某个节点放入序列时,该节点会维护其标识,并将该标识重复到相同序列中。
序列与 节点集非常不同,后者是未排序的,并仅包含没有重复的节点。尽管节点集是未排序
的,但是它们仍然由 按文档顺序进行处理。为了有助于维护向后兼容性,!路径表
达式始终以不带重复项的文档顺序生成序列(该保证不适用于其它表达式类型)。在 !中,只
需根据该序列的顺序来处理序列即可。正如您将在稍后所见,序列可以让您以更大的灵活性来控制处理。
!中的每个值都是序列。使用逗号分隔符在括号内编写序列,如下所示:
01-1H"!H 02H90(!;I;!J(22
该序列包含四个类型的值:分别是 9、9 @、9K以及 9。以下序列依次
包含 元素列表、元素列表以及 +7元素列表:
0$$ H$$H$$+72
空序列写为:02。实际上,原子值被认为是长度为 的序列(指单元素序列)。单元素序列可编写为
01-12或 1-1。二者之间没有不同。
序列的另一个重要特征是,它们都是平面的,即序列可能不包含其他序列。例如,以下三个序列完全相同:
0H!H"HJ2
00H!2H0"HJ22
0002H0!H"2H0J222
因为整个语言围绕序列而转,所以有各种运算符和函数可与它们协同使用。
集操作
我已经介绍了一个序列运算符,即逗号 01H12。逗号表示串联运算符,可将两个序列串联在一起,以维持
排序。有其他几个基于集的可用于序列的运算符:7701F12、以及 97。
运算符 F返回两个序列的并集,移除重复项(如在 中一样)。例如,假设
L、L!、L"以及 LJ全部都引用相互不同的节点,以下示例说明了一个并集:
0LHL!HL"2F0L!HL"HLJ2;<
0LHL!HL"HLJ2
运算符返回两个序列的交集,移除重复项:
00LHL!HL"20L!HL"HLJ2;<
0L!HL"2
运算符返回每个出现在第一个序列但不出现在第二个序列的节点,移除重复项:
0LHL!HL"2970L!HL"HLJ2;<
0L2
除这些集操作外,还有几个其他利于使用序列的函数。有关运算符的详细信息,请参阅
7$$"$=$9A :;7。
序列处理
!为基本列表操纵提供了预期函数:、#、#;、9;以及
@A 。前两个可用于从序列添加和移除项目,如下所示:
00H"HJ2H!H!2;<0H!H"HJ2
#00H!H"2H!2;<0H"2
函数 #;根据提供索引返回项目(相当于使用一个简单的定位谓词 %9)),而 9;函数返
回与提供值匹配的项目的位置:
9;00H!H"2H!2;<!
@A 返回由提供的开始和结束位置标识的连续子集(作为另一个序列)。
有几种方法可用于检查序列的长度。您可以使用 9、#7:和 。M9在序列不为空时返
回真,否则返回假。M#7:在序列为空时返回真,否则返回假。. 返回序列内的项目数,正如它在
中所做一样。
#7:0022;<
900H!H"22;<
00H!H"2;<"
还有几种方法可用于执行有关序列的数学运算: #、、#以及 #9:
#0H!H"2;<N
0H!H"2;<!
#0H!H"2;<
#90H!H"2;<"
我喜欢的与序列有关的函数是 ; 。该函数返回一个新序列,该序列只包含带有唯一值的项
(它移除了带有重复值的项目,如 ?中的 MM.+-.)。它假设序列包含所有节点或所有
值,否则会出现错误。以下表达式将标识出文档中所有的唯一 元素:
; 0$$ 2
这比 中相应的表达式便利:
$$ %07 '2)
还有一个 ;函数,它根据标识而不是值来移除重复的节点。
序列和谓词
在 中,可以通过圆括号将谓词应用到特定的节点集。考察以下表达式:
$$%)
第一眼看过去,它似乎像是以文档顺序返回 元素的表达式,但是,实际上,它将返回每个为其父
元素的第一个子元素的 元素(这是由于运算符优先级所致)。您可以通过在希望筛选的节点集外
使用圆括号来修复这个问题:
0$$2%)
该同一模型适用于序列。您可以使用谓词来筛选出不需要的项目。将谓词应用到序列,将返回一个新序列,
其中只包含满足谓词表达式的项目。例如,以下谓词将测试项目的位置(等同于 #;):
0H!H"2%!);<0!2
该示例使用稍许复杂的谓词来检查子元素的数量以及 属性的值:
LA% 0*2<&4)
一般而言,您在 中学到的有关谓词的知识,也可应用于 !中的序列上。
序列强制
如果您在需要另一个类型的上下文中使用序列,则会试图执行隐式强制。将序列强制为字符串、数字以及
布尔值的规则几乎与 中的规则相同。例如,如果要提供一个其中要求字符串的序列,则第一
项的值将会被强制为字符串并进行使用。用于计算节点的字符串值的规则如下所示:对于文本$属性而言,
它只是值,而对于元素而言,它是子代文本节点的串联。如果要提供一个其中要求数字的序列,则它首先
会被强制为字符串,然后再强制为 @。唯一稍许不同的规则是强制为布尔值的规则。如果序列为空,
则它会被强制为假。包含单个布尔值的序列被认为是假,否则会将至少包含一个节点的非空序列认为是真。
用于在字符串、数字以及布尔值类型之间显式强制的函数与 中的一样,并且有其他几个函数
可用于各种 架构数据类型(如 9、9 等)的强制,如本专栏之前所
述。
比较
最令人讨厌的地方之一是它对节点集比较的计算方式。例如,考察以下示例表达式:
.$$'GGI
如果至少(在 .$之下)存在一个带有数值为 GGI的 元素,则该表达式将计算为真。
当在布尔值表达式中也如此使用序列时,如果其任何成员的比较为真,则结果为真,否则就是所谓的存在
量化。有趣地是,这适用于任何比较运算符(4、4'、<、<'等),甚至是不等于 0O'2运算符,如以
下代码行所示:
.$$O'GGI
如果至少(在 .$之下)存在一个带有不等于 GGI的数值的 元素,则该表达式将计
算为真。因此,如果不是或许,就是非常有可能这两个比较都将为同一节点集返回真。无需多说,这就是
导致多数混淆的原因。
通过使用布尔值而不是函数,可以测试序列中的所有项,否则就是所谓的通用量化。例如,为了确定所有
的 元素都具有值 GGI,请使用以下逻辑而不是上一个表达式:
0.$$O'GGI2
为了验证单个 元素具有等于 GGI的数值,您必须使用以下逻辑而不是第一个表达式:
0.$$'GGI2
在 !中,它们通过辨别不同的比较表达式,以及使得在存在量化和通用量化之间进行显式选择
成为可能,来试图消除尽可能多的混淆。使用标准的 '、O'、4、4'、<以及 <'运算符的一般比较
表达式,会保持我介绍过的 的默认行为(存在量化或“:P语义),以保留向后兼容性。
它们还添加了几个新函数,即 A ;7;A 和 A ;;A ,用于分别根据值或
节点标识来比较两个序列。
!为简单的值比较定义了单独的机制。值比较使用以下运算符:A、、、、以及
(分别代表 '、O'、4、4'、<以及<'),但是对于比较如原子值之类的单个项,!提
供了一些附加的比较,以用于处理单个节点。例如,和 运算符测试节点标识:
%)%);<
%) %);<
您还可以使用 44和 <<运算符来测试节点排序。如果在文档顺序中,第一个操作数节点位于第二个操
作数节点之前,则 44运算符返回真。而 <<运算符刚好相反。因为值和节点表达式期望单元素,所以
“:P对“P语义完全不起作用。
显式量化
!还使得您可以通过新的表达式类型编写显式量化表达式。您可以表达,在将约束表达式(满
足条件)应用到提供序列的节点时,是希望使用存在(一些)量化还是通用(每个)量化:
#L#$$#Q
00L#$*L#$? :2<2
:L#$$#Q
00L#$*L#$? :2<2
如果至少有一个 #元素的总价 0*? :2大于 ,则第一个表达式返回真。如果每
个 #元素的总价都大于 ,则第二个表达式返回真。
因为约束表达式可以是任何内容,所以该模型提供了比 '、O'、4以及其他运算符更大的灵活性。而且,
它对于表达式涉及到的序列数量没有限制,如下面的检查提供序列的笛卡尔坐标的示例所示:
#L90H!H"2HL:0!H"HJ2
剩余63页未读,继续阅读
资源评论
- wfwyl2013-08-07内容还好,函数调用明确
- qunews2015-11-20这个相当不错,是个好东西.
msgsnd
- 粉丝: 30
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功