XPath 的工作方式

XPath 规范是各种规范的基础,其中包括 XSLT 和链接/寻址规范,例如XPointer。因此,了解 XPath 是许多高级 XML 使用的基础。本节介绍了 XSLT 上下文中的 XPath。

XPath Expressions

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

XPath 表达式中的节点不仅指元素。除其他外,它们还引用文本和属性。实际上,XPath 规范定义了一个抽象文档模型,该模型定义了七种节点:

  • Root

  • Element

  • Text

  • Attribute

  • Comment

  • Processing instruction

  • Namespace

XML 数据的根元素由 element 节点建模。 XPath 根节点包含文档的根元素以及与文档有关的其他信息。

XSLT/XPath 数据模型

像文档对象模型(DOM)一样,XSLT/XPath 数据模型由包含各种节点的树组成。在任何给定的元素节点下,都有文本节点,属性节点,元素节点,注解 节点和处理指令节点。

在此抽象模型中,语法上的区别消失了,您将获得数据的标准化视图。例如,在文本节点中,无论是在 CDATA 节中定义文本还是包含实体引用都没有关系。文本节点将由归一化的数据组成,因为所有解析完成后就存在。因此,无论是否使用诸如\<之类的实体引用或 CDATA 节将其包含在内,文本都将包含\<字符。 (类似地,文本将包含&字符,无论它是使用&传递的还是位于 CDATA 部分中)。

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

模板和上下文

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

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

表达式//LIST从 Importing 流中选择LIST个节点的集合。模板中的其他说明告诉系统如何处理它们。

由这样的表达式选择的节点集定义了上下文,在该上下文中可以评估模板中的其他表达式。该上下文可以视为整个集合-例如,在确定其包含的节点数时。

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

基本 XPath 寻址

XML 文档是节点的树结构(分层)集合。与分层目录结构一样,指定指向分层结构中特定节点的路径很有用(因此,规范名称为 XPath)。实际上,目录路径的许多符号是完整保留的:

  • 正斜杠(/)用作路径分隔符。

  • 从文档根目录开始的绝对路径以/开头。

  • 从给定位置开始的相对路径以其他任何内容开头。

  • Double 倍句点(..)表示当前节点的父节点。

  • 单个句点(.)表示当前节点。

例如,在可扩展 HTML(XHTML)文档(看起来像 HTML 但根据 XML 规则格式正确的 XML 文档)中,路径/h1/h2/表示h1下的h2元素。 (回想一下,在 XML 中,元素名称区分大小写,因此,这种规范在 XHTML 中比在纯 HTML 中更有效,因为 HTML 不区分大小写.)

在 Pattern 匹配规范(例如 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"\]选择类型值无序的所有LIST元素。

元素存在类似的表达。每个元素都有一个关联的字符串 值,该字符串 值是通过 String 联位于该元素下面的所有文本段而形成的。 (有关该过程如何工作的详细说明,请参见元素的字符串 值)。

假设您使用 XML 结构建模组织中正在发生的事情,该 XML 结构由具有项目名称的文本字符串 的PROJECT元素和ACTIVITY元素,用于列出相关人员的多个PERSON元素以及(可选)用于记录相关人员的STATUS元素组成项目状态。以下是使用扩展方括号表示法的其他示例:

  • /PROJECT\[\.="MyProject"\]:选择一个名为"MyProject"PROJECT

  • /PROJECT\[STATUS\]:选择所有具有STATUS子元素的项目。

  • /PROJECT\[STATUS="Critical"\]:选择所有具有STATUS子元素且字符串 值Critical的项目。

组合索引地址

XPath 规范定义了很多寻址机制,可以用许多不同的方式来组合它们。结果,XPath 为相对简单的规范提供了很多表达能力。本节说明了其他有趣的组合:

  • LIST\[@type="ordered"\]\[3\]:选择类型ordered的所有LIST个元素,并返回第三个元素。

  • LIST\[3\]\[@type="ordered"\]:选择第三个LIST元素,但仅当其类型为ordered时。


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


Wild Cards

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

表 4-1 XPath 通配符

Wild cardMeaning
\*匹配任何元素节点(不是属性或文本)。
node\(\)匹配任何种类的任何节点:元素节点,文本节点,属性节点,处理指令节点,名称空间节点或 注解 节点。
@\*匹配任何属性节点。

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

Extended-Path Addressing

到目前为止,您已经看到的所有 Pattern 都在层次结构中指定了确切数量的级别。例如,/HEAD指定层次结构中第一级的任何HEAD元素,而/\*/\*指定层次结构中第二级的任何元素。要在层次结构中指定不确定的级别,请使用 Double 斜杠(//)。例如,XPath 表达式//PARA选择文档中所有可能位于任何段落元素的元素。

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

XPath 数据类型和运算符

XPath 表达式产生一组节点,一个字符串,一个布尔值(一个真/假值)或一个数字。 Table 4-2列出了可以在 Xpath 表达式中使用的运算符:

表 4-2 XPath 运算符

OperatorMeaning
\|另类。例如,PARA\|LIST选择所有PARALIST元素。
or , and返回两个布尔值的或/和。
= , !=布尔值,字符串 和数字等于或不等于。
\< , \> , \<= , \>=小于,大于,小于或等于,大于或等于数字。
+ , \- , \* , div , mod加,减,乘,浮点除法和模数(余数)操作(例如 6 mod 4 = 2)。

表达式可以放在括号中,因此您不必担心运算符的优先级。


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


元素的字符串 值

元素的字符串 值是所有后代文本节点的 String 联,无论深度如何。考虑以下混合内容的 XML 数据:

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

\<PARA\>元素的字符串 值为 此段落包含粗体字 。特别要注意,\<B\>\<PARA\>的子代,而文本bold\<B\>的子代。

关键是节点的所有子级中的所有文本都将 String 联在一起形成字符串 值。

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

XPath Functions

本节以 XPath 功能的概述结尾。您可以使用 XPath 函数来选择节点集合,就像使用元素规范一样,例如已经看到的那些。其他函数返回字符串,数字或布尔值。例如,表达式/PROJECT/text\(\)获取PROJECT个节点的字符串 值。

许多功能取决于当前环境。在前面的示例中,每次调用text\(\)函数的上下文都是当前选定的PROJECT节点。

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

Node-Set Functions

许多 XPath 表达式选择一组节点。本质上,它们返回一个节点集。一个功能也可以做到这一点。 id\(\.\.\.\)函数返回具有指定 ID 的节点。 (仅当文档具有 DTD 时元素才具有 ID,该 DTD 指定哪个属性具有 ID 类型)。

Positional Functions

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

  • last\(\):返回最后一个元素的索引。例如,/HEAD\[last\(\)\]选择最后一个HEAD元素。

  • position\(\):返回索引位置。例如,/HEAD\[position\(\) \<= 5\]选择前五个HEAD元素。

  • count\(\.\.\.\):返回元素数。例如,/HEAD\[count\(HEAD\)=0\]选择没有子标题的所有HEAD元素。

String Functions

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

  • concat\(string, string, \.\.\.\):连接字符串 值。

  • starts\-with\(string1, string2\):如果string1string2开头,则返回 true。

  • contains\(string1, string2\):如果string1包含string2,则返回 true。

  • substring\-before\(string1, string2\):返回string2出现之前的string1的开头。

  • substring\-after\(string1, string2\):返回出现string2后剩余的string1

  • substring\(string, idx\):从索引位置到末尾(第一个char的索引= 1)返回子字符串。

  • substring\(string, idx, len\):从索引位置返回指定 Long 度的子字符串。

  • string\-length\(\):返回上下文节点的字符串 值的大小;上下文节点是当前选定的节点-由 XPath 表达式选择的节点,其中应用了string\-length\(\)之类的功能。

  • string\-length\(string\):返回指定字符串 的大小。

  • normalize\-space\(\):返回当前节点的规范化字符串 值(无前导或尾随空格,以及将空格字符序列转换为单个空格)。

  • normalize\-space\(string\):返回指定字符串 的规范化字符串 值。

  • translate\(string1, string2, string3\):转换string1,将string2中出现的字符替换为string3中的相应字符。


注意- XPath 定义了三种获取元素文本的方式:text\(\)string\(object\)和表达式中的元素名称所隐含的字符串 值:/PROJECT\[PERSON="Fred"\]


Boolean Functions

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

  • not\(\.\.\.\):否定指定的布尔值。

  • true\(\):返回 true。

  • false\(\):返回 false。

  • lang\(string\):如果上下文节点的语言(由xml:Lang属性指定)与指定语言相同(或其子语言),则返回 true;否则,返回 true。例如,\<PARA_xml:Lang="en"\>\.\.\.\</PARA\>的 Lang(“ en”)为 true。

Numeric Functions

这些函数对数字进行运算或返回数值。

  • sum\(\.\.\.\):返回指定节点集中每个节点的数值之和。

  • floor\(N\):返回不大于 N 的最大整数。

  • ceiling\(N\):返回不小于 N 的最小整数。

  • round\(N\):返回最接近 N 的整数。

Conversion Functions

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

  • string\(\.\.\.\):返回数字,布尔值或节点集的字符串 值。

  • boolean\(\.\.\.\):返回数字,字符串 或节点集的布尔值(非零数字,非空节点集和非空字符串 均为 true)。

  • number\(\.\.\.\):返回布尔值,字符串 或节点集的数值(true 为 1,false 为 0,包含数字的字符串 变为该数字,节点集的字符串 值转换为数字)。

Namespace Functions

这些功能使您可以确定节点的名称空间 Feature。

  • local\-name\(\):返回当前节点的名称,减去名称空间前缀。

  • local\-name\(\.\.\.\):返回指定节点集中第一个节点的名称,减去名称空间前缀。

  • namespace\-uri\(\):从当前节点返回名称空间 URI。

  • namespace\-uri\(\.\.\.\):从指定节点集中的第一个节点返回名称空间 URI。

  • name\(\):返回当前节点的 extensions 称(URI 加本地名称)。

  • name\(\.\.\.\):返回指定节点集中第一个节点的 extensions 称(URI 加本地名称)。

Summary

XPath 运算符,函数,通配符和节点寻址机制可以通过多种方式组合。到目前为止,您所进行的介绍应该为您指定任何特定 Object 所需的 Pattern 提供了一个很好的起点。