点击此处浏览总目录

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异常

 

posted @ 2019-11-13 16:43  立业的博客  阅读(520)  评论(0编辑  收藏  举报