ElementPath
ElementTree库附带了一个简单的类似XPath的路径语言ElementPath
主要区别在于,可以在ElementPath表达式中使用{namespace}标记符号
但是,诸如值比较和函数之类的高级功能不可用
只要树没有被修改,这个路径表达式就表示一个给定元素的标识符,以后可以用它在同一棵树中找到它
与XPath相比,ElementPath表达式具有自包含的优势,即使对于使用名称空间的文档也是如此
除了完整的XPath实现之外,lxml.etree支持ElementPath语言的方式与ElementTree相同
甚至使用(几乎)相同的实现。API在这里提供了四种方法,可以在Elements和ElementTrees上找到它们
iterfind(): 遍历与路径表达式匹配的所有元素
findall(): 返回匹配元素的列表
find(): 只有效地返回第一个匹配项
findtext(): 返回第一个匹配项的.text内容
# coding:utf-8 from lxml import etree #查找当前节点的子节点 root = etree.XML("<root><a x='123'>aText<b/><c/><b/></a></root>") print(root.find("b")) #输出:None,因为root的子节点是a print(root.find("a").tag) #输出:a #查找树中的任意节点 print(root.find(".//b").tag) #输出:b print([ b.tag for b in root.iterfind(".//b")]) #输出:['b', 'b'] #查找带指定属性的节点 print(root.findall(".//a[@x]")[0].tag) #输出:a print(root.findall(".//a[@y]")) #输出:[] #在lxml 3.4中,有一个新的功能为元素生成一个结构化的ElementPath表达式 tree = etree.ElementTree(root) a = root[0] print(tree.getelementpath(a[0])) #输出:a/b[1] print(tree.getelementpath(a[1])) #输出:a/c print(tree.getelementpath(a[2])) #输出:a/b[2] print(tree.find(tree.getelementpath(a[2])) == a[2]) #输出:True #.iter()方法是一种特殊情况,它只根据名称在树中查找特定标记,而不是基于路径 #这意味着以下命令在成功案例中是等价的 print(root.find(".//b").tag) #输出:b print(next(root.iterfind(".//b")).tag) #输出:b print(next(root.iter("b")).tag) #输出:b #注意,如果没有找到匹配项,.find()方法只返回None,而其他两个示例将引发StopIteration异常