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>]
