XPath提供了一种对XML节点、节点属性和内容快速查询的规则。在各种编程语言中都有实现,比如C语言的libxml2和对应的R包 xml2

1. 查询规则

XPath查询集中在三个对象:节点、节点属性和节点内容。

1.1 选择节点

  • /nodeA/nodeB:nodeA为根节点,nodeA下的所有nodeB节点;等价于nodeB

  • //nodeB:所有nodeB节点,在R包xml2中(比如函数xml_find_all()),//nodeB搜索范围是整个文档,忽略当前节点;而.//nodeB搜索范围是当前节点之下。

  • //nodeB[1]:所有nodeB节点的第一个;//nodeB[last()-1]:所有nodeB节点的倒数第二个;nodeA/nodeB[position()<3]:当前nodeA节点,其下所有nodeB子节点的前两个。

  • /nodeA/*:nodeA为根节点,nodeA下的所有节点;/*/*/nodeC:所有拥有两个父节点的nodeC节点;//*:所有节点。

  • //*[count(nodeD)=3]:含有3个nodeD子节点的节点;//*[count(*)=2]:含有任意2个子节点的节点。

  • //*[name()='nodeB']:所有名称为“nodeB”的节点,等价于//nodeB//*[starts-with(name(),'N')]:所有名称以“N”开头的节点;//*[contains(name(),'N')]:所有名称中含有“N”的节点;//*[string-length(name()) = 3]:所有名称的字符串长度等于3的节点。

  • //nodeA | //nodeB:所有nodeA,以及nodeB的节点,多个搜索条件合并,搜索添加没有限制。

1.2 选择节点属性

  • //@attr1:所有拥有attr1的属性,注意:返回的不是节点,而是类此attr1=text1的属性;//node1/@attr1:所有node1带有的attr1属性;//nodeB[@attr1]:所有拥有“attr1”属性的nodeB节点;//nodeB[@attr1='test1']:所有拥有“attr1”属性为“test1”的nodeB节点;//nodeB[normalize-space(@attr1)='test1']:所有拥有attr1属性为“test1”(属性去除字符串前后空格,内部连续空格替换为一个空格)的nodeB节点。

  • //node1[@*]:所有node1带有任意属性的节点;//node1[not(@*)]:所有node1不带属性的节点。

  • //node1[TEST1][TEST2]:多个属性形选择可以首位相接,依次判断是否为真。TEST1和TEST2同时为真,返回选择结果。//nodeA[nodeB/@attr1='test1']:选择所有nodeA节点,这些nodeA节点拥有nodeB子节点且属性“attr1”为“test1”。//nodeC[@attr1='test1'][../nodeB/@attr2='test2']:选择所有拥有“attr1”为“test1”的nodeC节点,而且这些nodeC节点有属性“attr2”为“test2”的nodeB父亲节点。

1.3 选择节点内容

  • /nodeA/nodeB[nodeC>5]:nodeA为根节点,nodeA下的nodeB节点,而且这些nodeB节点必须有nodeC子节点,并且nodeC子节点内容大于5。

  • /nodeA/nodeB[nodeC>5]/nodeD:nodeA为根节点,nodeA下的nodeB节点,而且这些nodeB节点必须有nodeC子节点,并且nodeC子节点内容大于5。

  • //nodeC[.=5]:所有nodeC节点,其内容等于5。使用.代替自身。

  • //nodeC/node():选择所有nodeC节点下的所有点,包括节点下内容和子节点(距离最近,不包括子节点的子节点)。

  • //nodeC/text():选择所有nodeC节点下的内容。

1.4 函数使用

  • //nodeC[contains(text(), 'test1')]:选择所有nodeC节点,而且nodeC节点下内容包括“test1”。

2. 轴

  • child:::默认轴,可以省略。比如/child::nodeA等价于/AAA

  • descendant:::选择上下文节点的所有子节点、子节点的子节点、子节点的子节点的子节点(依次类推,直至最后一个子节点)。//nodeA/descendant::*:所有nodeA节点的所有子节点、子节点的子节点等等;//nodeA/descendant::nodeC:所有nodeA节点的所有的nodeC子节点,nodeC可能是nodeA的某个子节点的子节点,区别与//nodeA/nodeD/descendant::*:文档所有子节点、子节点的子节点等等,等价于//*

  • descendant-or-self::*:选择上下文节点自身及其所有子节点、子节点的子节点(依次类推,直至最后一个子节点)。

  • parent:::选择上下文节点的父节点(最靠近的父节点)。//nodeC/parent::*:所有nodeC节点的所有父节点;//nodeC/parent::nodeA[@attr1='test1']:nodeC节点的nodeA父节点,这些nodeA父节点的“attr1”属性等于“test1”。

  • ancestor:::选择上下文节点的父节点,父节点的父节点(依次类推,直至最前一个父节点,包括根节点)。//nodeC/ancestor::nodeA:所有nodeC的父节点和父节点的父节点等等中的nodeA节点。

  • ancestor-or-self::::选择上下文节点自身及其所有父节点,父节点的父节点(依次类推,直至最前一个父节点,包括根节点)。

  • following-sibling:::选择与上下文节点等级相同(即深度相同)的且位置靠后(上为前,下为后)的兄弟节点。//nodeC/following-sibling::*:所有nodeC节点等级相同的且位置靠后的兄弟节点。

  • preceding-sibling:::同following-sibling::,也是兄弟节点但位置靠前。

  • following:::选择上下文节点之后的所有节点(包括对应的子节点),但除了根节点。//nodeC/following::*:所有nodeC节点之后的所有节点。

  • preceding:::选择上下文节点之前的所有节点(包括对应的子节点),但除了根节点。

  • //nodeC/ancestor::* | //nodeC/descendant::* | //nodeC/following::* | //nodeC/preceding::* | //nodeC/self::*:所有节点,等价于//*或者等价于/descendant::*

参考网址

更新记录

2015年10月24日

Comments