我有一个函数可以从etree元素返回一个列表,但它不会查看嵌套元素。
<elem>
<variable id="getthis">
<!-- / -->
</variable>
<if>
<variable id="alsoGetThis">
<!-- Keep looping through all elements -->
</variable>
</if>
</elem>
(我正在使用Valid XML)
所以目前忽略了<if>
中的变量,那么如何循环遍历树的所有层次?我假设这是一项简单的任务,但也许我错了。 (我是Python的新手,并且总是像程序员一样思考)
Python func获取变量:
def collect_vars(self, elem):
elemVars = []
if elem.tag == 'variable':
elemVars.append(elem.attrib['id'])
elif e in elem == 'variable': # don't want to be doing these
elemVars.append(e.attrib['id'])
return elemVars
所以我想最终得到的是包含给定elemVars
<elem>
答案 0 :(得分:4)
考虑学习XPath并使用LXML的xpath
成员。假设您的XML树名为t
,就像您发布了
>>> s = """<elem>
<variable id="getthis">
<!-- / -->
</variable>
<if>
<variable id="alsoGetThis">
<!-- Keep looping through all elements -->
</variable>
</if>
</elem>
"""
>>> t = etree.fromstring(s)
然后你可以用
找到树中的所有元素>>> t.xpath("//*")
[<Element elem at 0x2809b40>, <Element variable at 0x2809be0>, <Element if at 0x2809af0>, <Element variable at 0x2809c80>]
以及
的所有variable
元素
>>> t.xpath("//variable")
[<Element variable at 0x2809be0>, <Element variable at 0x2809c80>]
xpath
返回满足您指定的XPath条件的元素列表,表示为元素树:
>>> [x.attrib["id"] for x in t.xpath("//variable")]
['getthis', 'alsoGetThis']
答案 1 :(得分:1)
您遇到的问题是您没有访问文件中的所有节点。您只访问elem
元素的子元素,但您没有访问这些元素的子元素。为了说明这一点,运行以下内容(我已将您的XML编辑为有效):
from xml.etree.ElementTree as etree
xml_string = """<elem>
<variable id="getthis" />
<if>
<variable id="alsoGetThis" />
</if>
</elem>"""
e = etree.fromstring(xml_string)
for node in e:
print node
结果
<Element variable at 7f53fbdf1cb0>
<Element if at 7f53fbdf1cf8>
因此,您没有访问节点variable
的子if
。您将需要递归访问XML文件中的每个节点,即您的函数collect_vars
将需要调用自身。我会稍微发布一些代码来说明这一点。
编辑:正如所承诺的,有些代码可以从元素树中获取所有id
属性。我没有使用蓄能器作为Niek de Klein,而是使用了发电机。这具有许多优点。例如,这会一次返回id
个,因此您可以在任何时候停止处理,例如,遇到某个id
,这样可以节省读取整个XML文件的时间。< / p>
def get_attrs(element, tag, attr):
"""Return attribute `attr` of `tag` child elements of `element`."""
# If an element has any cildren (nested elements) loop through them:
if len(element):
for node in element:
# Recursively call this function, yielding each result:
for attribute in get_attrs(node, tag, attr):
yield attribute
# Otherwise, check if element is of type `tag` with attribute `attr`, if so
# yield the value of that attribute.
if element.tag == 'variable':
if attr in element.attrib:
yield element.attrib[attr]
ids = [id for id in get_attrs(e, 'variable', 'id')]
print ids
此产生结果
['getthis', 'alsoGetThis']