xpath语法以及基本使用
XPath 是一种用于在 XML 文档中查找信息的语言。它被广泛应用于 XML 解析和处理。XPath 提供了丰富的语法和功能,可以精确地定位和筛选 XML 文档中的元素和属性。
基本语法
1. 路径表达式
/
:选择根节点。//
:从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。.
:选择当前节点。..
:选择当前节点的父节点。@
:选择属性。
2. 节点选取
nodename
:选取此节点的所有子节点。*
:匹配任何元素节点。@*
:匹配任何属性节点。node()
:匹配任何类型的节点。
3. 谓语(Predicates)
[]
:用于查找特定的节点。[n]
:选取第 n 个子节点(从 1 开始)。[@attr]
:选取具有指定属性的节点。[text()='value']
:选取文本内容为指定值的节点。
- 谓语用来过滤节点。写在方括号
[]
中。例如,//book[price>35.00]
选择价格大于35.00的所有book
节点。- 可以在谓语中使用逻辑运算符(如
and
、or
)以及关系运算符(如=
,!=
,<
,>
,<=
,>=
)
4. 轴(Axes)
child::
:选取子节点。parent::
:选取父节点。ancestor::
:选取当前节点的所有祖先(父、祖父等)。descendant::
:选取当前节点的所有后代(子、孙等)。following-sibling::
:选取当前节点之后的所有同级节点。preceding-sibling::
:选取当前节点之前的所有同级节点。
- 例如,
child::book
选择当前节点的所有book
子节点。
5. 函数
text()
:选取文本节点。contains()
:检查是否包含指定的文本。starts-with()
:检查是否以指定的文本开头。position()
:返回当前节点的位置。last()
:返回当前节点集中的最后一个节点的位置。
- 例如,
//book/title/text()
选择所有book
元素的title
子节点的文本。
6. 组合路径
可以组合多种路径表达式来定位更复杂的节点。例如,/bookstore/book/title | //book/author
选择所有bookstore
下的book
元素的title
子节点,以及文档中所有book
元素的author
子节点。
示例xml
<library xmlns:bk="http://example.com/books">
<book id="1">
<title>XML Developer's Guide</title>
<author>Author 1</author>
<price>44.95</price>
</book>
<book id="2">
<title>Midnight Rain</title>
<author>Author 2</author>
<price>5.95</price>
</book>
<book id="3">
<title>Maeve Ascendant</title>
<author>Author 3</author>
<price>5.95</price>
</book>
<bk:book id="4">
<bk:title>Oberon's Legacy</bk:title>
<bk:author>Author 4</bk:author>
<bk:price>5.95</bk:price>
</bk:book>
</library>
查找单个元素
查找第一个 <title>
元素
/library/book[1]/title
查找 <book>
元素中 id
为 2
的 <title>
元素
/library/book[@id='2']/title
查找 author是Author 2 且price 是5.95的title
/library/book[author='Author 3' and price='5.95']/title
查找多个元素
查找所有 <title>
元素
//title
查找所有价格为 5.95
的 <book>
元素
//book[price='5.95']
查找深层次元素
查找所有 <author>
元素
//author
查找所有 <book>
元素的 <title>
元素
//book/title
根据指定的筛查条件查找
查找价格大于 10
的所有 <book>
元素
//book[price > 10]
查找包含 Rain
的 <title>
元素
//title[contains(text(), 'Rain')]
处理命名空间
查找命名空间 bk
中的 <title>
元素
//bk:book/bk:title
这里假设已经声明了bk前缀与http://example.com/books URI的映射关系。
使用local-name()
函数
如果不希望或不能使用命名空间前缀,可以使用local-name()
函数来匹配不考虑命名空间的元素名称。但是,这种方法不能单独用于定位具有特定命名空间的节点,它通常与其他条件结合使用。
例如,要找到所有本地名称为book
的元素,不考虑它们的命名空间,可以使用:
//*[local-name()='book']
但是,如果要同时考虑命名空间,还需要结合其他条件,如namespace-uri()
函数。
使用namespace-uri()
函数:
namespace-uri()
函数返回节点的命名空间URI。可以结合local-name()
函数来定位具有特定命名空间和本地名称的节点。
例如,要找到命名空间为http://example.com/books
且本地名称为book
的元素,可以使用:
注意and两边的空格,有的第三方库不支持空格,可以使用连写
//*[local-name()='book' and namespace-uri()='http://example.com/books']
在XPath处理器中声明命名空间:
许多XPath处理器允许在查询之前声明命名空间前缀与URI的映射关系。这样,在查询中就可以直接使用这些前缀,而不需要在查询字符串中显式地指定它们。
例如,在某些编程环境中,可以像这样声明命名空间:(python中可以这样写)
namespaces = {'abc': 'http://example.com/books'}
result = tree.xpath('//abc:book/abc:title', namespaces=namespaces)
这里,namespaces
是一个字典,它将前缀映射到URI,然后在xpath
方法中传递这个字典。