我正在处理一个巨大的xml文件,并尝试从不同的元素中提取信息。
import xml.etree.ElementTree as ET
tree = ET.parse('t.xml')
root = tree.getroot()
要查找元素,我使用find方法:
elm = root.find('.//Element[@elmid="1234"]')
由此我提取信息,此外我需要来自父元素的信息。但elm.find('..')
仅返回None
,如下所示:
https://docs.python.org/3/library/xml.etree.elementtree.html
现在我使用下面的内容:
prt = root.find('.//Element[@elmid="1234"]/..')
elm = prt.find('/Element[@elmid="1234"]')
这对我来说看起来有点不自然,但有效。
你知道更好的方法吗?
你知道为什么只返回None
吗?
答案 0 :(得分:15)
xml.etree
API仅支持限制版本的XPath。 ..
XPath表达式状态的xml.etree
docs:
选择父元素。 如果路径尝试,则返回None 到达start元素的祖先(元素find被调用 上)。强>
直接获取父元素是not supported in the xml.etree
API。因此,我建议使用lxml
,您只需使用getparent()
获取父元素:
elm = root.find('.//Element[@elmid="1234"]')
elm.getparent()
lxml
也有一个完整的XPath 1.0 implementation,因此elem.xpath('..')
也会有效。
答案 1 :(得分:0)
我有一个类似的问题,我有点创意。事实证明,没有什么阻止我们自己添加育儿信息。以后我们不再需要它时就可以剥离它。
def addParentInfo(et):
for child in et:
child.attrib['__my_parent__'] = et
addParentInfo(child)
def stripParentInfo(et):
for child in et:
child.attrib.pop('__my_parent__', 'None')
stripParentInfo(child)
def getParent(et):
if '__my_parent__' in et.attrib:
return et.attrib['__my_parent__']
else:
return None
tree = ...
addParentInfo(tree.getroot())
el = tree.findall(...)[0]
parent = getParent(el)
while parent:
...
parent = getParent(parent)
...
stripParentInfo(tree.getroot())