您的位置:寻梦网首页编程乐园XML 编程XML技术讲座
XML 编程

XML技术讲座之十一

XPointer语言

XPointer语言的主要功能是在XML文件中定位片段(fragement),在XML链接中,通常将它加到URL的结尾,更明确地表示目标资源。但是XPointer语言的使用并不局限于XML链接,它可以用于在需要文档内部定位的任何地方,比如在可视化的XML编辑器中用于描述用户选择的节点或字符串。

XPointer语言概述

HTML中的文件内部定位非常简单,就是在目标文件中插入一个命名锚(named anchor),然后用链接元素<A>的href属性指定链接的位置即可。但这种机制存要求你同时控制目标文件和开始文件,而这并不总是成立。由于XML是结构化的文件,借助文件结构进行内部定位就成为可能,这就是XPointer语言,它支持在XML文件中定位元素、属性、字符串等内部结构。

XPointer语言基于XSLT中的XPath,支持完整形式(Full XPointers)、无修饰名称(bare names)或子节点序列(Child Sequences)三种形式以定位片段。完整形式的XPointer的形式为xpointer(表达式),其中表达式用于定位计算,得到需要的资源片断,所有的定位计算都基于一个已知节点,该节点称为上下文节点。一般而言,最初始的上下文节点总是文档中的确定位置,如文档的根节点(注意:根节点不是根元素,它是一个抽象的节点,是根元素的父节点,用"/"表示)、文档中具有确定ID值的元素(用函数id()表示)、当前元素(用函数here()表示)等。无修饰名称只有一个名称,表示文件中ID等于指定名称的元素,它提供了与HTML文件兼容的方式以定位文档片段。子节点序列由名称、一系列数字和"/"组成的序列,其中"/"用于分隔名称和数字,数字n表示前面定位元素的第n个直接子元素,子节点序列必须以"/1"或名称打头,表示该序列从根元素或指定ID的元素开始。实际上,后面两种形式都是第一种形式的简写,下面是几种形式的XPointer的例子。

xpointer(/child::lang/descendent::body[position()<=2])
xpointer(id("location")) 简写为:location
xpointer(/child::*[position()=1]/child::*[position()=2]) 简写为: /1/2
xpointer(id("loc")/child::*[position()=3]/child::*[position()=4]) 简写为:loc/3/4

XPath位置步

与XPath语言一样,XPointer语言中的表达式是多个位置步形成的一个位置路径,每个位置步间用"/"分隔,前面位置步的运算结果构成后面位置步的上下文节点。位置步的形式为axis::node-test[prediates],它包括三个部分:

  • 关键字,有且仅有一个,它表示结果节点与上下文节点的关系;
  • 节点测试,有且仅有一个,它表示结果节点的类型或名称;
  • 谓词,零到多个,它可以是用于限制结果的任意表达式。

在下面的例子中,第一个"/"表示文档的根节点,"child::lang"为第一个位置步,"descendent::body[position()<=2]"为第二个位置步,这两个位置步链接形成一个位置路径。在第二个位置步中,"descendent"是关键字,"body"是节点测试,"position()<=2"是谓词。

/child::lang/descendent::body[position()<=2]

关键字的运算基于上下文节点,如果上下文节点有多个,它将对上下文节点逐一进行计算。下面列出了用于XPointer中的XPath关键字。

(1) ancestor:上下文节点的所有祖先节点,即包含上下文节点的所有节点。显然,根节点没有祖先节点。

(2) ancestor-or-self:上下文节点及其所有祖先节点。

(3) attribute:上下文节点的所有属性,如果上下文节点不是元素类型,结果集为空,attribute关键字可以简写为"@"。

(4) child:上下文节点的直接子节点,包括元素、处理指令、注释、文本,但不包括属性。child关键字是缺省的。

(5) descendant:上下文节点的所有后代节点,不包括属性和命名空间节点。简写为"//"。

(6) descendant-or-self:上下文节点及其所有后代节点。

(7) following:处于上下文节点后的节点。第一个节点从上下文节点结束标记后的第一个开始标记开始。返回元素顺序按文件顺序排列。

(8) following-sibling:上下文节点后,并与上下文节点具有相同父节点的节点。按文件顺序计算。

(9) parent:上下文节点的父节点,即直接包含上下文节点的节点。如果没有节点测试,可以简写为".."

(10) preceding:开始于整个上下文节点前的所有节点,不包括祖先节点。返回元素顺序按文件逆序排列。

(11) preceding-sibling:开始于上下文节点前,并与上下文节点具有相同父节点的节点。

(12) self:上下文节点。可以简写为"."

节点测试用于测试节点类型或名称,只有那些满足节点测试的节点才会保留在初始的结果集中,以待下一步的谓词过滤。在很多情况下,节点测试是一个名称,但并不总是如此,其它的节点测试还有:

(1) *。通配符"*"表示所有的元素,它不考虑元素的名称,通配符"*"只选择元素类型。如果你希望选择所有节点,可以用node()表示。

(2) node()。节点测试node()表示所有类型的节点,包括元素、注释、文本、处理指令等。

(3) comment()。表示类型是注释的节点。

(4) processing-instruction()。表示类型是处理指令的节点。它还可以接收参数,表示指定名称的处理指令。

(5) text()。表示类型是文本的节点。

谓词是对结果集进行过滤的表达式,一般是布尔型,其他类型的表达式可以转化为布尔型。XPointer中,表示位置的谓词是最常用的谓词,包括几个谓词函数position()、last()等。position()表示节点在结果集中的序号,序号从1开始,一般而言,结果集中的节点是按照相对于上下文节点的距离排序。position()函数常与关系运算符(=、<>、<、<=、>、>=)、数字连用,构成关系表达式,表示结果结点满足此关系表达式。谓词[position()=n]常简写为[n]。last()表示集合中的节点数目,也可与position()函数连用。

XPointer扩展

前面介绍的定位方式来源于XPath,它们同时适用于XPath和XPointer,但是XPointer对XPath进行了扩展。其扩展主要包括:

(1) 将XPath的节点(node)扩展为位置(location),位置可以是节点、点和区域;点是某个节点或字符前后的位置,区域是两个点之间的所有结构和数据。

(2) 增加了函数here() 和origin()用于进行位置定位,表示当前元素,其中here()用于本地资源,origin()用于远程资源;

(3) 增加函数point()以定位点。如果点的包含结构可以包含节点,这种类型的点称为节点点(node point),此时索引按照节点进行,0表示第一个节点前的位置,n表示第n个节点前的位置;如果点的包含结构不能包含节点,这种类型的点称为字符点(character point),此时索引按照字符进行。

(4) 增加了区域表达式,用于生成区域;其形式为xpointer(start-point/range-to(end-point)),其中start-point是一个位置路径,表示区域的起始点,end-point是另一个位置路径,表示区域的结束点,range-to()是一个函数,其参数是位置路径,表示整个位置路径的计算结果是一个区域。

(5) 增加函数string-range(),用于生成字符串;其形式为string-range(location-set,substring,index,length),其中location-set表示字符串匹配的范围,substring表示匹配字符串,index表示相对于匹配位置的起始点length表示返回字符串的长度;

(6) 增加函数start-point() 和end-point(),用于定位节点或区域的起始点和结束点;

(7) 增加谓词函数unique(),用于测试XPointer表达式是否只返回一个位置,而不是多个位置或没有返回位置。

XPointer转义

由于XPointer不是单独出现,而一些字符不能直接出现在包含XPointer的上下文中,因此这些字符必须转义出现。首先,XML文件中不能直接出现的"<"、"&"、"""、"'"必须转义出现,转义方法与XML规范相同;其次,XPointer出现在URI中时,不能直接出现在URI中的字符必须转义出现,主要包括非ASCII字符,转义为"%HH"形式,HH是该字符的十六位编码;另外,XPointer语言要求不匹配的括号必须转义,转义方法是在不匹配的括号前面加上"^",如果表达式中出现"^",则在前再加一个"^"。

来源:网络世界