-
XPath 示例
./author | 当前上下文中的所有 <author> 元素。注意,此表达式等效于下一行中的表达式。 |
author | 当前上下文中的所有 <author> 元素。 |
first.name | 当前上下文中的所有 <first.name> 元素。 |
/bookstore | 本文档的文档元素 (<bookstore> )。 |
//author | 文档中的所有 <author> 元素。 |
book[/bookstore/@specialty = @style] | style 属性值等于文档根目录的 <bookstore> 元素的 specialty 属性值的所有 <book> 元素。 |
author/first-name | 属于 <author> 元素的子级的所有 <first-name> 元素。 |
bookstore//title | <bookstore> 元素中更深的一级或多级(任意子代)的所有 <title> 元素。注意,此表达式不同于下一行中的表达式。 |
bookstore/*/title | 属于 <bookstore> 元素的孙级的所有 <title> 元素。 |
bookstore//book/excerpt//emph | <book> 元素的 <excerpt> 子级中的任意位置和 <bookstore> 元素中的任意位置的所有 <emph> 元素。 |
.//title | 当前上下文中更深的一级或多级的所有 <title> 元素。注意,本质上只有这种情况需要句点表示法。 |
author/* | 属于 <author> 元素的子级的所有元素。 |
book/*/last-name | 属于 <book> 元素的孙级的所有 <last-name> 元素。 |
*/* | 当前上下文的所有孙级元素。 |
*[@specialty] | 具有 specialty 属性的所有元素。 |
@style | 当前上下文的 style 属性。 |
price/@exchange | 当前上下文中 <price> 元素的 exchange 属性。 |
price/@exchange/total | 返回空节点集,因为属性不包含元素子级。XML 路径语言 (XPath) 语法允许使用此表达式,但是严格意义上讲无效。 |
book[@style] | 当前上下文的具有 style 属性的所有 <book> 元素。 |
book/@style | 当前上下文的所有 <book> 元素的 style 属性。 |
@* | 当前元素上下文的所有属性。 |
./first-name | 当前上下文节点中的所有 <first-name> 元素。注意,此表达式等效于下一行中的表达式。 |
first-name | 当前上下文节点中的所有 <first-name> 元素。 |
author[1] | 当前上下文节点中的第一个 <author> 元素。 |
author[first-name][3] | 具有 <first-name> 子级的第三个 <author> 元素。 |
my:book | my 命名空间中的 <book> 元素。 |
my:* | my 命名空间中的所有元素。 |
@my:* | my 命名空间中的所有属性(不包括 my 命名空间中的元素的未限定属性)。 |
注意,索引相对于父级。考虑以下数据:
- <x>
- <y />
- <y />
- </x>
- <x>
- <y />
- <y />
- </x>
x/y[1] | 每个 <x> 的第一个 <y> 子级。此表达式等效于下一行中的表达式。 |
x/y[position() = 1] | 每个 <x> 的第一个 <y> 子级。 |
(x/y)[1] | <x> 元素的整个 <y> 子级元素集中的第一个 <y> 。 |
x[1]/y[2] | 第一个 <x> 的第二个 <y> 子级。 |
其他示例引用 《XPath 语法的示例 XML 文件》。
book[last()] | 当前上下文节点的最后一个 <book> 元素。 |
book/author[last()] | 当前上下文节点的每个 <book> 元素的最后一个 <author>子级。 |
(book/author)[last()] | 当前上下文节点的 <book> 元素的整个 <author> 子级元素集中的最后一个 <author> 元素。 |
book[excerpt] | 至少包含一个 <excerpt> 元素子级的所有 <book> 元素。 |
book[excerpt]/title | 属于 <book> 元素(也至少包含一个 <excerpt> 元素子级)的子级的所有 <title> 元素。 |
book[excerpt]/author[degree] | 至少包含一个 <degree> 元素子级并且属于 <book> 元素(也至少包含一个 <excerpt> 元素)子级的所有<author> 元素。 |
book[author/degree] | 所有包含 <author> 子级的 <book> 元素,该子级至少包含一个 <degree> 子级。 |
author[degree][award] | 至少包含一个 <degree> 元素子级以及至少包含一个<award> 元素子级的所有 <author> 元素。 |
author[degree and award] | 至少包含一个 <degree> 元素子级以及至少包含一个<award> 元素子级的所有 <author> 元素。 |
author[(degree or award) and publication] | 至少包含一个 <degree> 或 <award> 以及至少包含一个<publication> 子级的所有 <author> 元素。 |
author[degree and not(publication)] | 至少包含一个 <degree> 元素子级并且不包含<publication> 元素子级的所有 <author> 元素。 |
author[not(degree or award) and publication] | 至少包含一个 <publication> 元素子级并且不包含<degree> 和 <award> 元素子级的所有 <author> 元素。 |
author[last-name = "Bob"] | 至少包含一个值为 Bob 的 <last-name> 元素子级的所有<author> 元素。 |
author[last-name[1] = "Bob"] | 第一个 <last-name> 子元素的值为 Bob 的所有 <author>元素。注意,此表达式等效于下一行中的表达式。 |
author[last-name [position()=1]= "Bob"] | 第一个 <last-name> 子元素的值为 Bob 的所有 <author>元素。 |
degree[@from != "Harvard"] | from 属性不等于 "Harvard" 的所有 <degree> 元素。 |
author[. = "Matthew Bob"] | 所有值为 Matthew Bob 的 <author> 元素。 |
author[last-name = "Bob" and ../price > 50] | 包含值为 Bob 的 <last-name> 子元素以及值大于 50 的<price> 同辈元素的所有 <author> 元素。 |
book[position() <= 3] | 前三本书(1、2、3)。 |
author[not(last-name = "Bob")] | 不包含值为 Bob 的 <last-name> 子元素的所有 <author>元素。 |
author[first-name = "Bob"] | 至少包含一个值为 Bob 的 <first-name> 元素的所有<author> 元素。 |
author[* = "Bob"] | 所有包含任何值为 Bob 的子元素的 author 元素。 |
author[last-name = "Bob" and first-name = "Joe"] | 所有包含值为 Bob 的 <last-name> 子元素和值为 Joe 的<first-name> 子元素的 <author> 元素。 |
price[@intl = "Canada"] | 上下文节点中所有 intl 属性等于 "Canada" 的 <price> 元素。 |
degree[position() < 3] | 属于上下文节点子级的前两个 <degree> 元素。 |
p/text()[2] | 上下文节点中每个 <p> 元素的第二个文本节点。 |
ancestor::book[1] | 与上下文节点最接近的 <book> 上级。 |
ancestor::book[author][1] | 与上下文节点最接近的 <book> 上级,并且此 <book> 元素包含 <author> 元素子级。 |
ancestor::author[parent::book][1] | 当前上下文中最接近的 <author> 上级,并且此 <author>元素是 <book> 元素的子级。 |
附: 《XPath 语法的示例 XML 文件》
- <?xml version="1.0"?>
- <?xml-stylesheet type="text/xsl" href="myfile.xsl" ?>
- <bookstore specialty="novel">
- <book style="autobiography">
- <author>
- <first-name>Joe</first-name>
- <last-name>Bob</last-name>
- <award>Trenton Literary Review Honorable Mention</award>
- </author>
- <price>12</price>
- </book>
- <book style="textbook">
- <author>
- <first-name>Mary</first-name>
- <last-name>Bob</last-name>
- <publication>
- Selected Short Stories of
- <first-name>Mary</first-name>
- <last-name>Bob</last-name>
- </publication>
- </author>
- <editor>
- <first-name>Britney</first-name>
- <last-name>Bob</last-name>
- </editor>
- <price>55</price>
- </book>
- <magazine style="glossy" frequency="monthly">
- <price>2.50</price>
- <subscription price="24" per="year" />
- </magazine>
- <book style="novel" id="myfave">
- <author>
- <first-name>Toni</first-name>
- <last-name>Bob</last-name>
- <degree from="Trenton U">B.A.</degree>
- <degree from="Harvard">Ph.D.</degree>
- <award>Pulitzer</award>
- <publication>Still in Trenton</publication>
- <publication>Trenton Forever</publication>
- </author>
- <price intl="Canada" exchange="0.7">6.50</price>
- <excerpt>
- <p>It was a dark and stormy night.</p>
- <p>
- But then all nights in Trenton seem dark and stormy to
- someone who has gone through what
- <emph>I</emph>
- have.
- </p>
- <definition-list>
- <term>Trenton</term>
- <definition>misery</definition>
- </definition-list>
- </excerpt>
- </book>
- <my:book xmlns:my="uri:mynamespace" style="leather" price="29.50">
- <my:title>Who's Who in Trenton</my:title>
- <my:author>Robert Bob</my:author>
- </my:book>
- </bookstore>
引自 http://jiangzhengjun.iteye.com/blog/483048
XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。
XML 实例文档
我们将在下面的例子中使用这个 XML 文档。
<?xml version="1.0" encoding="ISO-8859-1"?> <bookstore> <book> <title lang="eng">Harry Potter</title> <price>29.99</price> </book> <book> <title lang="eng">Learning XML</title> <price>39.95</price> </book> </bookstore>
选取节点
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。
下面列出了最有用的路径表达式:
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
实例
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:
路径表达式 | 结果 |
---|---|
bookstore | 选取 bookstore 元素的所有子节点。 |
/bookstore | 选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
//book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang | 选取名为 lang 的所有属性。 |
谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
实例
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang='eng'] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
选取未知节点
XPath 通配符可用来选取未知的 XML 元素。
通配符 | 描述 |
---|---|
* | 匹配任何元素节点。 |
@* | 匹配任何属性节点。 |
node() | 匹配任何类型的节点。 |
实例
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
/bookstore/* | 选取 bookstore 元素的所有子元素。 |
//* | 选取文档中的所有元素。 |
//title[@*] | 选取所有带有属性的 title 元素。 |
选取若干路径
通过在路径表达式中使用“|”运算符,您可以选取若干个路径。
实例
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
//book/title | //book/price | 选取 book 元素的所有 title 和 price 元素。 |
//title | //price | 选取文档中的所有 title 和 price 元素。 |
/bookstore/book/title | //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
引自 http://www.w3school.com.cn/xpath/xpath_syntax.asp
XPath 表达式的上下文
XPath 表达式的计算取决于运算表达式所针对的上下文。 上下文包括计算表达式所针对的节点及其关联的环境,包括下列内容:
-
上下文节点相对于同辈节点的位置(按文档顺序)。
-
上下文的大小 — 即上下文节点的同辈节点数加 1。
-
可以解析变量引用的变量绑定。
-
函数库。
-
表达式范围中的命名空间声明。
为了更好地评价上下文的概念,请考虑包含节点的树。 向树根请求所有名为 X 的节点时,将返回一个结果集,而向树枝请求这些节点时,将返回不同的结果集。 因此,表达式的结果取决于执行表达式所针对的上下文。
XPath 表达式可以在一个特定的上下文匹配特定的模式,返回结果,然后相对于所返回节点的上下文执行其他运算。 这样,在整个文档树中进行搜索时,使用 XPath 表达式非常灵活。
运算符和特殊字符
XPath 表达式是使用下表中所示的运算符和特殊字符构造的。
/ | 子运算符;选择左侧集合的直接子级。 此路径运算符出现在模式开头时,表示应从根节点选择该子级。 |
// | 递归下降;在任意深度搜索指定元素。 此路径运算符出现在模式开头时,表示应从根节点递归下降。 |
. | 指示当前上下文。 |
.. | 当前上下文节点的父级。 |
* | 通配符;选择所有元素,与元素名无关。 |
@ | 属性;属性名的前缀。 |
@* | 属性通配符;选择所有属性,与名称无关。 |
: | 命名空间分隔符;将命名空间前缀与元素名或属性名分隔。 |
( ) | 为运算分组,明确设置优先级。 |
[ ] | 应用筛选模式。 |
[ ] | 下标运算符;用于在集合中编制索引。 |
+ | 执行加法。 |
- | 执行减法。 |
div | 根据 IEEE 754 执行浮点除法。 |
* | 执行乘法。 |
mod | 从截断除法返回余数。 |
此表不包括布尔运算符和集运算符,这两个运算符在布尔、比较和集表达式或集运算中列出。
优先级顺序(从最高优先级到最低优先级)的定义如下表所示。
优先级 | 字符 | 用途 |
---|---|---|
1 | ( ) | 分组 |
2 | [ ] | 筛选器 |
3 | / // | 路径运算 |
分组运算符 () 仅适用于顶级路径表达式。 例如,(//author/degree | //author/name) 是有效的分组运算,但 //author/(degree | name) 不是。
筛选模式运算符 ([]) 的优先级高于路径运算符(/ 和 //)。 例如,表达式 //comment()[3] 选择相对于文档中任意位置备注的父级索引等于 3 的所有备注。 此表达式与表达式(//comment())[3] 不同,后者选择相对于父级的所有备注集中的第三个备注。 前一个表达式可以返回多个备注,后一个表达式只能返回一个备注。
这些运算符和特殊字符在本参考文档中详细说明。
表达式 | 引用 |
---|---|
author/first-name | 当前上下文节点的 <author> 元素中的所有 <first-name> 元素。 |
bookstore//title | <bookstore> 元素中一级或多级深度的所有 <title> 元素(任意后代)。 注意,此表达式与以下模式 bookstore/*/title 不同。 |
bookstore/*/title | 作为 <bookstore> 元素的孙代的所有 <title> 元素。 |
bookstore//book/excerpt//emph | <book> 元素的 <excerpt> 子级中的任意位置和 <bookstore> 元素中的任意位置的所有 <emph> 元素: |
.//title | 当前上下文中一级或多级深度的所有 <title> 元素。 注意,本质上只有这种情况需要句点表示法。 |
使用 @* 可以返回某个元素的所有属性。 对于将属性作为记录中的字段的应用程序,此表达式可能非常有用。
示例
表达式 | 引用 |
---|---|
@* | 当前上下文节点的所有属性。 |
@my:* | my 命名空间中的所有属性。 不包括 my 命名空间中的元素的未限定特性。 |
注意,不支持模式 @*:title。
更加详细内容见微软网站 http://msdn.microsoft.com/zh-cn/library/ms256471(v=vs.110).aspx
Dom4j使用xpath的例子
下面的例子是取出子文件夹的ID和文件夹名的集合
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* Test App
*
*/
public class App
{
public static void main( String[] args ) throws DocumentException
{
xpathTest();
}
/**
* XPath syntax test method
* @throws DocumentException
*/
@SuppressWarnings("rawtypes")
private static void xpathTest() throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read("d:/2.xml");
Element root = document.getRootElement();
String xpath = "/folder/fields/folder";
List lstNodes = root.selectNodes(xpath);
for (Iterator ir = lstNodes.iterator(); ir.hasNext(); ) {
Element elm = (Element)ir.next();
System.out.println(elm.attributeValue("id"));
System.out.println(elm.selectSingleNode("fields/field[@name='NAME']").getText());
}
}
}
<?xml version="1.0"?>
<folder id="1091" type="None">
<fields>
<field name="NAME">General</field>
<folder id="1092" >
<fields>
<field name="NAME">Test01</field>
</fields>
</folder>
<folder id="1093" >
<fields>
<field name="NAME">Test02</field>
</fields>
</folder>
</fields>
</folder>