Xpath 是一种能够在 XML 文档中寻找信息的语言。它通过 XML 文档中的元素和属性来进行导航。
你应具备的知识
在你继续前你应该具备以下知识的基础:
什么是XPath?
XPath 是针对 XML 文档部分内容定义的语法
XPath 使用路径表达式在 XML 文档中导航
XPath 包含了一系列标准函数
XPath 在 XSLT 当中是一个主要的元素
XPath 是 W3C 标准
XPath 路径表达式
XPath 使用路径表达式来选择 XML 文档中的 nodes( 节 ) 或是 node-set( 节集 ) 。这些路径表达式看上去与你平时所见的传统计算机文件系统路径非常地相似。
XPath 标准函数
XPath 包含了数量超过 100 的内置函数。这些函数针对字符串值,数字值,日期和时间比较,节操作,顺序操作,布尔值,等等。
XPath被用在XSLT
在 XSLT 标准中 XPath 是主要的元素。没有 XPath 知识你将很难建立 XSLT 文档。
XQuery 和 XPointer 都建立于 XPath 表达式。 XQuery 1.0 和 XPath 2.0 共享相同的数据模型并支持相同的函数和操作
XPath是W3C标准
XPat 于 1999 年 11 月 16 日 成为 W3C 的推荐标准
XPath 被设计成为用语 XSLT,XPoniter 以及其他 XML 解析的软件。
翻译: Linyupark / 2006-03-24
在 XPath 中有七种 nodes( 节 ) :元素,属性,文字,命名空间,处理说明,注释,和文档 ( 根 ) 节。
XPath术语
XML 文档被视为数状的节。树的根部被称为文档的节 ( 或根节 ) 。
观察下面的 XML 文档:
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
上面举例的 XML 文档的节有:
原子值
原子值是那些没有子或父的节(无上下关系)。
举例中的原子值:
项目
项目是原子值或节。
节之间的关系
每个元素和属性有一父亲。
下面的举例中: book 元素是 title , author , year 和 price 的父亲
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
元素节可能有 0 个或多个子
下面的举例中: title,author,year 和 price 元素都是 book 元素的子元素
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
指那些有相同父的
下面的举例中 title, author, year, 和 price 元素都为兄弟
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
节的父,父的父 .... 都为祖
下面的举例中: book 元素和 bookstore 元素都为 title 元素的祖元素
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
节的子,子的子 ... 都为孙
下面的举例中: bookstore 元素的孙有 book,title,author,year 以及 price 元素
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
翻译: Linyupark / 2006-03-24
XPath 使用路径表达式来选择 XML 文档的节或是节集。顺着路径或步骤来选择节。
XML实例文档
举例中我们将使用下面的 XML 文档
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
选择节
一些非常有用的路径表达式:
表达式
|
描述
|
nodename
|
Selects all child nodes of the node[
选择所有目前节的子节
]
|
/
|
Selects from the root node[
从根节进行选择
]
|
//
|
Selects nodes in the document from the current node that match the selection no matter where they are [
选择文档中相吻合的节而不管其在文档的何处
]
|
.
|
Selects the current node[
选择当前节
]
|
..
|
Selects the parent of the current node[
当前节的父节
]
|
@
|
Selects attributes[
选择属性
]
|
实例
下面我们所列举的表格有路径表达式以及其结果:
路径表达式
|
结果
|
bookstore
|
Selects all the child nodes of the bookstore element[
选择所有
bookstore
元素的子节
]
|
/bookstore
|
Selects the root element bookstore
Note:
If the path starts with a slash ( / ) it always represents an absolute path to an element!
[
选择了
bookstore
的根元素。注意:如果路径的开始为
(/)
那此路径一定是到该元素的绝对路径
]
|
bookstore/book
|
Selects all book elements that are children of bookstore[
选择了所有在
bookstore
的子元素
book
元素所包含的所有元素(其实就为
bookstore
里
book
元素所包含的元素)
]
|
//book
|
Selects all book elements no matter where they are in the document[
选择所有为
book
元素的内容而不管
book
元素处于何处
(
有不同的父也没关系
)]
|
bookstore//book
|
Selects all book elements that are descendant of the bookstore element, no matter where they are under the bookstore element[
在
bookstore
元素内所有含有
book
元素的元素内容(只要
book
元素的祖元素为
bookstore
元素那都符合条件)
]
|
//@lang
|
Selects all attributes that are named lang[
选择所有属性名为
lang
的属性
]
|
谓语
谓语用来指定明确的节所含有的特殊的值
谓语被嵌入在中括号
举例
下面的表格列举了一些使用了谓语的路径表达式以及其产生的结果:
路径表达式
|
结果
|
/bookstore/book[1]
|
Selects the first book element that is the child of the bookstore element[
选择了
bookstore
里的第一个
book
元素
]
|
/bookstore/book[last()]
|
Selects the last book element that is the child of the bookstore element[
选择
bookstore
里最后一个
book
元素
]
|
/bookstore/book[last()-1]
|
Selects the last but one book element that is the child of the bookstore element[bookstore
中倒数第二个
book
元素
]
|
/bookstore/book[position()<3]
|
Selects the first two book elements that are children of the bookstore element[
在
bookstore
中前两个
book
元素
]
|
//title[@lang]
|
Selects all the title elements that have an attribute named lang[
选择所有含有
lang
属性的
title
元素
]
|
//title[@lang='eng']
|
Selects all the title elements that have an attribute named lang with a value of 'eng'[
选择所有含有
lang
属性并且值为
eng
的
title
元素
]
|
/bookstore/book[price>35.00]
|
Selects all the book elements of the bookstore element that have a price element with a value greater than 35.00[
选择所有
bookstore
中
book
元素里
price
元素内容大于
35.00
的
book
元素
]
|
/bookstore/book[price>35.00]/title
|
Selects all the title elements of the book elements of the bookstore element that have a price element with a value greater than 35.00[
选择
bookstore
中
book
的子元素
title
,并且其兄弟元素
price
的内容得大于
35.00]
|
选择未知的节
XPath 的通配符可以用来选择未知的 XML 元素
通配符
|
描述
|
*
|
Matches any element node[
相吻合的所有元素节
]
|
@*
|
Matches any attribute node[
相吻合的所有属性节
]
|
node()
|
Matches any node of any kind[
吻合任何类型的节
]
|
下面的表格我们将列举一些路径表达式以及它们的结果
路径表达式
|
结果
|
/bookstore/*
|
Selects all the child nodes of the bookstore element[
选择所有
bookstore
的子节
]
|
//*
|
Selects all elements in the document[
选择所有文档中的元素
]
|
//title[@*]
|
Selects all title elements which have any attribute[
选择元素为
title
并且其含有属性
]
|
选择数个路径
通过在 XPath 中使用 | 你可以选择数个路径
实例
下面的表格我们会列举一些路径表达式以及其结果:
路径表达
|
结果
|
//book/title | //book/price
|
Selects all the title AND price elements of all book elements[
选择所有
book
里
title
和
price
元素
]
|
//title | //price
|
Selects all the title AND price elements in the document[
选择所有
title
和
price
元素
]
|
/bookstore/book/title | //price
|
Selects all the title elements of the book element of the bookstore element AND all the price elements in the document[
选择所有
book
里的
title
元素和所有
price
元素
]
|
翻译: Linyupark / 2006-03-24
XML举例文档
我么将使用该 XML 文档进行下面的举例说明
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
XPath轴
轴定义了相对于当前节的节集
轴名
|
结果
|
ancestor
|
Selects all ancestors (parent, grandparent, etc.) of the current node[
选择了当前节的所有祖(父,祖父,等等)
]
|
ancestor-or-self
|
Selects all ancestors (parent, grandparent, etc.) of the current node and the current node itself[
选择当前节的所有祖并且还有当前节自己
]
|
attribute
|
Selects all attributes of the current node[
选择所有当前节的属性
]
|
child
|
Selects all children of the current node[
选择所有当前节的子
]
|
descendant
|
Selects all descendants (children, grandchildren, etc.) of the current node[
选择所有当前节的孙(子,孙子,等等)
]
|
descendant-or-self
|
Selects all descendants (children, grandchildren, etc.) of the current node and the current node itself[
选择当前节的所有孙以及它本身
]
|
following
|
Selects everything in the document after the closing tag of the current node[
选择所有在关闭当前节标签后的所有内容
]
|
following-sibling
|
Selects all siblings after the current node[
选择所有当前节后的兄
]
|
namespace
|
Selects all namespace nodes of the current node[
选择所有当前节的命名空间
]
|
parent
|
Selects the parent of the current node[
选择当前节的父
]
|
preceding
|
Selects everything in the document that is before the start tag of the current node[
选择当前节之前的所有内容
]
|
preceding-sibling
|
Selects all siblings before the current node[
选择所有当前节之前的兄
]
|
self
|
Selects the current node[
选择当前节
]
|
路径表达试定位
定位路径可以是绝对的也可以是相对的
绝对定位的路径由 (/) 开始,而相对定位就不这样。定位的路径由一个或多个步骤所组成,每部分由 (/) 相分隔:
在当前的节集中每步的赋值是逆向的
定位的语法
实例
Example
|
结果
|
child::book
|
Selects all book nodes that are children of the current node[
选择当前节点下所有为
book
的子节点
]
|
attribute::lang
|
Selects the lang attribute of the current node[
选择当前节点下所有属性为
lang
的内容
]
|
child::*
|
Selects all children of the current node[
选择当前节下所有的子节
]
|
attribute::*
|
Selects all attributes of the current node[
选择当前节所有的属性
]
|
child::text()
|
Selects all text child nodes of the current node[
选择当前节点所有子节点的文字
]
|
child::node()
|
Selects all child nodes of the current node[
选择所有当前节点的子节点
]
|
descendant::book
|
Selects all book descendants of the current node[
选择当前节点所有为
book
的孙节点
]
|
ancestor::book
|
Selects all book ancestors of the current node[
选择所有当前祖节点为
book
的节点
]
|
ancestor-or-self::book
|
Selects all book ancestors of the current node - and the current as well if it is a book node[
当前节点和其祖节点为
book
的节点
]
|
child::*/child::price
|
Selects all price grandchildren of the current node[
当前节点所有含
price
的孙子节点
]
|
翻译:无 / 2006-03-24
Operator
|
Description
|
Example
|
Return value
|
|
|
Computes two node-sets
|
//book | //cd
|
Returns a node-set with all book and cd elements
|
+
|
Addition
|
6 + 4
|
10
|
-
|
Subtraction
|
6 - 4
|
2
|
*
|
Multiplication
|
6 * 4
|
24
|
div
|
Division
|
8 div 4
|
2
|
=
|
Equal
|
price=9.80
|
true if price is 9.80 false if price is 9.90 |
!=
|
Not equal
|
price!=9.80
|
true if price is 9.90 false if price is 9.80 |
<
|
Less than
|
price<9.80
|
true if price is 9.00 false if price is 9.80 |
<=
|
Less than or equal to
|
price<=9.80
|
true if price is 9.00 false if price is 9.90 |
>
|
Greater than
|
price>9.80
|
true if price is 9.90 false if price is 9.80 |
>=
|
Greater than or equal to
|
price>=9.80
|
true if price is 9.90 false if price is 9.70 |
or
|
or
|
price=9.80 or price=9.70
|
true if price is 9.80 false if price is 9.50 |
and
|
and
|
price>9.00 and price<9.90
|
true if price is 9.80 false if price is 8.50 |
mod
|
Modulus (division remainder)
|
5 mod 2
|
1
|
翻译: Linyupark / 2006-03-24
让我们来尝试通过观察一些实例来学习基础的 XPath 语法
我们将使用下面这个 XML 文档来进行实例
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
选择节点
我们使用了 XMLDOM 对象来加载 XML 文档并用 selectNode() 函数来进行 XML 文档上节点的选择:
xmlDoc.async="false"
xmlDoc.load("books.xml")
选择所有book节点
下面这个实例就会选择所有 bookstore 元素以下的 book 节点:
选择第一个book节点
选择prices
选择price大于35的price节点
选择Price大于35的title节点
例子:
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd country="USA">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<price>10.90</price>
</cd>
<cd country="UK">
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<price>9.90</price>
</cd>
<cd country="USA">
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<price>9.90</price>
</cd>
</catalog>
定位节点
XML是树状结构,类似档案系统内数据夹的结构,XPath也类似档案系统的路径命名方式。不过XPath 是一种模式(Pattern),可以选出 XML档案中,路径符合某个模式的所有节点出来。例如要选catalog底下的cd中所有price元素可以用:
/catalog/cd/price
如果XPath的开头是一个斜线(/)代表这是绝对路径。如果开头是两个斜线(//)表示文件中所有符合模式的元素都会被选出来,即使是处于树中不同的层级也会被选出来。以下的语法会选出文件中所有叫做cd的元素(在树中的任何层级都会被选出来):
//cd
选择未知的元素
使用星号(Wildcards,*)可以选择未知的元素。下面这个语法会选出/catalog/cd 的所有子元素:
/catalog/cd/*
以下的语法会选出所有catalog的子元素中,包含有price作为子元素的元素。
/catalog/*/price
以下的语法会选出有两层父节点,叫做price的所有元素。
/*/*/price
以下的语法会选择出文件中的所有元素。
//*
要注意的是,想要存取不分层级的元素,XPath语法必须以两个斜线开头(//),想要存取未知元素才用星号(*),星号只能代表未知名称的元素,不能代表未知层级的元素。
选择分支
使用中括号可以选择分支。以下的语法从catalog的子元素中取出第一个叫做cd的元素。XPath的定义中没有第0元素这种东西。
/catalog/cd[1]
以下语法选择catalog中的最后一个cd元素:(XPathj并没有定义 first() 这种函式喔,用上例的 [1]就可以取出第一个元素。
/catalog/cd[last()]
以下语法选出含有price子元素的所有/catalog/cd元素。
/catalog/cd[price]
以下语法选出price元素的值等于10.90的所有/catalog/cd元素
/catalog/cd[price=10.90]
以下语法选出price元素的值等于10.90的所有/catalog/cd元素 的price元素
/catalog/cd[price=10.90]/price
选择一个以上的路径
使用Or操作数(|)就可以选择一个以上的路径。例如:
/catalog/cd/title | catalog/cd/artist
选择所有title以及artist元素
//title | //artist
选择所有title以及artist以及price元素
//title | //artist | //price
选择属性
在XPath中,除了选择元素以外,也可以选择属性。属性都是以@开头。例如选择文件中所有叫做country的属性:
//@country
选择所有含有country这个属性的cd元素:
//cd[@country]
以下语法选择出含有属性的所有cd元素
//cd[@*]
以下语法选择出country属性值为UK的cd元素
//cd[@country='UK']