文档

Java™教程
隐藏目录
XPath的工作原理
路径:Java XML处理API(JAXP)
课程:可扩展样式表语言转换

XPath的工作原理

XPath规范是多种规范的基础,包括XSLT和链接/寻址规范,例如XPointer。因此,对XPath的理解对于许多高级XML用法至关重要。本节在XSLT的上下文中介绍XPath。

XPath表达式

一般来说,XPath表达式指定了选择一组XML节点的模式。然后,XSLT模板在应用转换时使用这些模式。(另一方面,XPointer添加了定义“点”或“范围”的机制,以便可以使用XPath表达式进行寻址)。

XPath表达式中的节点不仅指元素,还包括文本和属性等其他内容。事实上,XPath规范定义了一个抽象的文档模型,其中定义了七种节点类型:

XML数据的根元素由一个元素节点模拟。XPath根节点包含文档的根元素以及与文档相关的其他信息。

XSLT/XPath数据模型

与文档对象模型(DOM)类似,XSLT/XPath数据模型由包含各种节点的树组成。在给定的元素节点下,有文本节点、属性节点、元素节点、注释节点和处理指令节点。

在这个抽象模型中,语法上的区别消失了,你得到的是数据的规范化视图。例如,在文本节点中,无论文本是在CDATA部分中定义的还是包含实体引用,都没有区别。文本节点将包含规范化数据,即在所有解析完成后存在的数据。因此,文本将包含“<”字符,无论是否使用了实体引用(如“<”)或CDATA部分来包含它。(类似地,文本将包含“&”字符,无论是使用“&”还是在CDATA部分中使用它)。

在本节中,我们将主要处理元素节点和文本节点。其他寻址机制,请参阅XPath规范。

模板和上下文

XSLT模板是应用于由XPath表达式选择的节点的一组格式化指令。在样式表中,XSLT模板可能如下所示:

<xsl:template match="//LIST">
    ...
</xsl:template>

表达式//LIST从输入流中选择了一组LIST节点。模板中的其他指令告诉系统如何处理它们。

由这样一个表达式选择的节点集合定义了模板中其他表达式求值的上下文。这个上下文可以被视为整个集合 - 例如,用于确定它包含的节点数。

上下文也可以被视为集合的一个成员,因为每个成员都是一个接一个地处理的。例如,在LIST处理模板内,表达式@type指的是当前LIST节点的type属性。(类似地,表达式@*指的是当前LIST元素的所有属性)。

基本XPath寻址

XML文档是一个树形结构(分层)的节点集合。与层次化目录结构一样,指定一个指向层次结构中特定节点的路径(因此规范的名称是XPath)非常有用。实际上,大部分目录路径的表示法都保持不变:

例如,在可扩展HTML(XHTML)文档(一种看起来像HTML但符合XML规则的XML文档)中,路径/h1/h2/表示h1下的h2元素。(回想一下,在XML中,元素名区分大小写,因此这种规范在XHTML中比在普通HTML中效果更好,因为HTML是不区分大小写的)。

在与模式匹配规范(如XPath)中,规范/h1/h2选择所有位于h1元素下的h2元素。要选择特定的h2元素,可以使用方括号[]进行索引(类似于数组中使用的方括号)。因此,路径/h1[4]/h2[5]将选择第四个h1元素下的第五个h2元素。


注意 - 在XHTML中,所有元素名都是小写的。这是XML文档的一个非常常见的约定。然而,在像本教程这样的教程中,大写名字更容易阅读。因此,在接下来的XSLT课程中,所有XML元素名都将大写。(属性名,另一方面,将保持小写)。


XPath表达式中指定的名称是指一个元素。例如,在/h1/h2中的h1指的是一个h1元素。要引用一个属性,您需要用@符号前缀属性名。例如,@type指的是一个元素的type属性。假设您有一个带有LIST元素的XML文档,例如,表达式LIST/@type将选择LIST元素的type属性。


注意 - 因为表达式没有以/开头,所以该引用相对于当前上下文的列表节点 - 无论文档中的位置如何。


基本XPath表达式

XPath表达式的完整范围利用了XPath定义的通配符、运算符和函数。您很快就会了解更多相关知识。这里,我们只介绍其中几个最常见的XPath表达式。

表达式@type="unordered"指定了一个名为type的属性,其值为unordered。类似LIST/@type的表达式指定了LIST元素的type属性。

您可以将这两种表示法结合起来得到一些有趣的结果。在XPath中,方括号表示法([])通常用于索引,但它也可以用来指定选择条件。因此,表达式LIST[@type="unordered"]选择所有type值为unordered的LIST元素。

类似的表达式也适用于元素。每个元素都有一个关联的字符串值,该值由连接元素下的所有文本段组成。(有关该过程的更详细解释,请参见元素的字符串值)。

假设您使用一个XML结构来建模组织中的活动,该结构由PROJECT元素和带有项目名称的文本字符串的ACTIVITY元素组成,还包括多个PERSON元素以列出相关人员,以及一个可选的STATUS元素来记录项目状态。以下是其他使用扩展的方括号表示法的示例:

组合索引地址

XPath规范定义了相当多的地址机制,并且它们可以以许多不同的方式组合。因此,XPath在相对简单的规范中提供了很多表达能力。本节介绍了其他有趣的组合:


注意:更多地址运算符的组合在XPath规范的2.5节中列出。这可能是定义XSLT转换的最有用的规范部分。


通配符

根据定义,一个未限定的XPath表达式选择与指定的模式匹配的一组XML节点。例如,/HEAD匹配所有顶级HEAD条目,而/HEAD[1]只匹配第一个。表 4-1列出了可以在XPath表达式中使用的通配符,以扩大模式匹配的范围。

表 4-1 XPath通配符

通配符

含义

*

匹配任何元素节点(不包括属性或文本)。

node()

匹配任何类型的节点:元素节点、文本节点、属性节点、处理指令节点、命名空间节点或注释节点。

@*

匹配任何属性节点。

在项目数据库示例中,/*/PERSON[.="Fred"]匹配任何以Fred命名的PROJECTACTIVITY元素。

扩展路径定位

到目前为止,你所见到的所有模式都指定了层级结构中的确切层级数。例如,/HEAD指定层级结构中第一级的任何HEAD元素,而/*/*指定层级结构中第二级的任何元素。要指定层级结构中的不确定层级,可以使用双斜杠(//)。例如,XPath表达式//PARA选择文档中的所有段落元素,无论它们在哪里找到。

模式//也可以在路径中使用。因此,表达式/HEAD/LIST//PARA表示从/HEAD/LIST开始的子树中的所有段落元素。

XPath数据类型和运算符

XPath表达式的结果可以是一组节点、一个字符串、一个布尔值(true/false),或一个数字。表 4-2列出了XPath表达式中可用的运算符:

表 4-2 XPath运算符

运算符

含义

|

选择。例如,PARA|LIST选择所有PARALIST元素。

orand

返回两个布尔值的或/与结果。

=!=

等于或不等于,适用于布尔值、字符串和数字。

<><=>=

小于、大于、小于或等于、大于或等于,适用于数字。

+-*divmod

加、减、乘、浮点除法和模(余数)运算(例如,6 mod 4 = 2)。

表达式可以用括号分组,这样你就不用担心运算符的优先级。


注意 - 运算符的优先级是回答这个问题的一个术语:“如果你指定 a + b * c,这是表示 (a+b) * c 还是 a + (b*c)?”(运算符的优先级与表中显示的大致相同)。


元素的字符串值

元素的字符串值是所有后代文本节点的连接,无论有多深。考虑下面的混合内容XML数据:

<PARA>This paragraph contains a <b>bold</b> word</PARA>

<PARA> 元素的字符串值是 This paragraph contains a bold word。特别要注意的是 <B><PARA> 的子元素,而文本 bold<B> 的子元素。

重点是节点的所有子节点的文本都会连接起来形成字符串值。

此外,值得理解的是XPath定义的抽象数据模型中的文本是完全规范化的。所以无论XML结构中是否包含实体引用 &lt;<CDATA 部分中,元素的字符串值都会包含 < 字符。因此,在使用XSLT样式表生成HTML或XML时,你必须将 < 的出现转换为 &lt; 或将其置于 CDATA 部分中。类似地, & 的出现必须转换为 &amp;

XPath函数

本节结束时概述了XPath函数。你可以使用XPath函数以与你已经看到的元素规范相同的方式选择一组节点。其他函数返回一个字符串、一个数字或一个布尔值。例如,表达式 /PROJECT/text() 获取 PROJECT 节点的字符串值。

许多函数依赖于当前上下文。在上面的例子中,每次调用 text() 函数的上下文是当前选择的 PROJECT 节点。

有很多XPath函数 - 太多了,无法在这里详细描述。本节提供了一个简要的列表,显示了可用的XPath函数以及它们的功能摘要。有关函数的更多信息,请参阅XPath规范的第4节。

节点集函数

许多XPath表达式选择一组节点。实质上,它们返回一个节点集。一个函数也是如此。 id(...) 函数返回具有指定ID的节点(仅当文档有DTD时,元素才有ID,DTD指定了具有ID类型的属性)。

位置函数

这些函数返回基于位置的数值。

字符串函数

这些函数对字符串进行操作或返回字符串。


注意 - XPath 定义了三种获取元素文本的方式:text()string(object),以及在表达式中的元素名称暗示的字符串值,例如:/PROJECT[PERSON="Fred"]


布尔函数

这些函数对布尔值进行操作或返回布尔值。

数字函数

这些函数操作或返回数字值。

转换函数

这些函数将一种数据类型转换为另一种数据类型。

命名空间函数

这些函数允许您确定节点的命名空间特性。

摘要

XPath 运算符、函数、通配符和节点定位机制可以以多种方式组合使用。到目前为止,你所学到的内容应该能够帮助你为特定目的指定所需的模式。


上一页:介绍XSL、XSLT和XPath
下一页:将DOM作为XML文件输出