[XPath/Python] XPath 与 lxml (二)XPath 语法

XPath 选取节点时使用的表达式是一种路径表达式。节点是通过路径(path)或者步(steps)来选取的。

 

本章使用以下 XML 文档作为示例。

<?xml version="1.0" encoding="utf8"?>
<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 的路径表达式都是基于某个节点之上的,例如最初的当前节点一般是根节点,这与 Linux 下路径切换原理是一样的。

 

表达式 描述
nodename 选取已匹配节点下名为 nodename 的子元素节点。
/ 如果以 / 开头,表示从根节点作为选取起点。
// 在已匹配节点后代中选取节点,不考虑目标节点的位置。
. 选取当前节点。
.. 选取当前节点的父元素节点。
@ 选取属性。

 

 

 

 

 

 

 

>>> from lxml import etree
>>> xml = """<?xml version="1.0" encoding="utf8"?>
<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>"""


# 得到根节点
>>> root = etree.fromstring(xml)  
>>> print root
<Element bookstore at 0x2c9cc88>

# 选取所有book子元素
>>> root.xpath(book)  
[<Element book at 0x2d88878>, <Element book at 0x2d888c8>]

# 选取根节点bookstore
>>> root.xpath(/bookstore)  
[<Element bookstore at 0x2c9cc88>]

# 选取所有book子元素的title子元素
>>> root.xpath(book/title)  
[<Element title at 0x2d88878>, <Element title at 0x2d888c8>]

# 以根节点为始祖,选取其后代中的title元素
>>> root.xpath(//title)    
[<Element title at 0x2d88878>, <Element title at 0x2d888c8>]

# 以book子元素为始祖,选取后代中的price元素
>>> root.xpath(book//price)  
[<Element price at 0x2ca20a8>, <Element price at 0x2d88738>]

# 以根节点为始祖,选取其后代中的lang属性值
>>> root.xpath(//@lang)    
[eng, eng]

 

预判(Predicates)

预判是用来查找某个特定的节点或者符合某种条件的节点,预判表达式位于方括号中。

# 选取bookstore的第一个book子元素
>>> root.xpath(/bookstore/book[1])          
[<Element book at 0x2ca20a8>]

# 选取bookstore的最后一个book子元素
>>> root.xpath(/bookstore/book[last()])        
[<Element book at 0x2d88878>]

# 选取bookstore的倒数第二个book子元素
>>> root.xpath(/bookstore/book[last()-1])      
[<Element book at 0x2ca20a8>]

# 选取bookstore的前两个book子元素
>>> root.xpath(/bookstore/book[position()<3])    
[<Element book at 0x2ca20a8>, <Element book at 0x2d88878>]

# 以根节点为始祖,选取其后代中含有lang属性的title元素
>>> root.xpath(//title[@lang])     
[<Element title at 0x2d888c8>, <Element title at 0x2d88738>]

# 以根节点为始祖,选取其后代中含有lang属性并且值为eng的title元素
>>> root.xpath("//title[@lang=‘eng‘]")    
[<Element title at 0x2d888c8>, <Element title at 0x2d88738>]

# 选取bookstore子元素book,条件是book的price子元素要大于35
>>> root.xpath("/bookstore/book[price>35.00]")    
[<Element book at 0x2ca20a8>]

# 选取bookstore子元素book的子元素title,条件是book的price子元素要大于35
>>> root.xpath("/bookstore/book[price>35.00]/title") 
[<Element title at 0x2d888c8>]

 

通配符

通配符 描述
*  匹配任何元素。
@* 匹配任何属性。
node() 匹配任何类型的节点。

 

 

 

 

# 选取 bookstore 所有子元素
>>> root.xpath(/bookstore/*)  
[<Element book at 0x2d888c8>, <Element book at 0x2ca20a8>]

# 选取根节点的所有后代元素
>>> root.xpath(//*)  
[<Element bookstore at 0x2c9cc88>, <Element book at 0x2d888c8>, <Element title at 0x2d88738>, <Element price at 0x2d88878>, <Element book at 0x2ca20a8>, <Element title at 0x2d88940>, <Element price at 0x2d88a08>]

# 选取根节点的所有具有属性节点的title元素
>>> root.xpath(//title[@*])  
[<Element title at 0x2d88738>, <Element title at 0x2d88940>]

# 选取当前节点下所有节点。‘\n    ‘ 是文本节点。
>>> root.xpath(node())  
[\n    , <Element book at 0x2d888c8>, \n    , <Element book at 0x2d88878>, \n]

# 选取根节点所有后代节点,包括元素、属性、文本。
>>> root.xpath(//node())  
[<Element bookstore at 0x2c9cc88>, \n    , <Element book at 0x2d888c8>, \n        , <Element title at 0x2d88738>, Harry Potter, \n        , <Element price at 0x2d88940>, 29.99, \n    , \n    , <Element book at 0x2d88878>, \n        , <Element title at 0x2ca20a8>, Learning XML, \n        , <Element price at 0x2d88a08>, 39.95, \n    , \n]

 

或条件选取

使用 "|" 运算符,你可以选取符合“或”条件的若干路径。

# 选取所有book的title元素或者price元素
>>> root.xpath(//book/title|//book/price)  
[<Element title at 0x2d88738>, <Element price at 0x2d88940>, <Element title at 0x2ca20a8>, <Element price at 0x2d88a08>]

# 选择所有title或者price元素
>>> root.xpath(//title|//price)  
[<Element title at 0x2d88738>, <Element price at 0x2d88940>, <Element title at 0x2ca20a8>, <Element price at 0x2d88a08>]

# 选择book子元素title或者全部的price元素
>>> root.xpath(/bookstore/book/title|//price)  
[<Element title at 0x2d88738>, <Element price at 0x2d88940>, <Element title at 0x2ca20a8>, <Element price at 0x2d88a08>]

[XPath/Python] XPath 与 lxml (二)XPath 语法,布布扣,bubuko.com

[XPath/Python] XPath 与 lxml (二)XPath 语法

上一篇:python 在调用时计算默认值


下一篇:【Java】 Thinking in Java 4.8 练习9