我很震惊,我可以使用VBA而不是python执行以下操作。我试图从api解析返回的xml为可用的格式。基于以下结构示例,这需要执行嵌套循环。麻烦的是最外面的循环从树中返回一个分离的元素,因此findall或iterfind什么也得不到,嵌套循环中止。我尝试使用3.4.1和2.7.8并获得相同的结果。这对我来说毫无意义。
import xml.etree.ElementTree as ET
data = """
<root>
<c1>
<c2>C2 Value 1</c2>
<s1>
<s2> S2 Value 1</s2>
<p1>
<p2>P2 Value 1</p2>
</p1>
<p1>
<p2>P2 Value 2</p2>
</p1>
</s1>
<s1>
<s2> S2 Value 2</s2>
<p1>
<p2>P2 Value 3</p2>
</p1>
</s1>
</c1>
</root>
"""
def use_et():
doc = ET.fromstring(data)
result = ['','','']
for c in doc.findall('.//c2'):
result[0] = c.text
# nothing here executes
# c is a detached Element. list(c) = []
for s in c.findall('..//s2'):
result[1] = s.text
for p in s.iterfind('..//p2'):
result[2] = p.text
print(','.join(result))
use_et()
答案 0 :(得分:2)
是的,来自xml.etree
的行为似乎很奇怪。看起来它适用于第三方lxml模块,尽管我认为它仍然更快:
>>> import lxml.etree as ET
>>> doc = ET.fromstring(data)
>>> c = doc.find('.//c2')
>>> c
<Element c2 at 0x10bdc3ef0>
>>> c.findall('..//s2')
[<Element s2 at 0x10bdc8a28>, <Element s2 at 0x10bdc8950>]
答案 1 :(得分:1)
假设您正在寻找第一个值,您可以执行此操作而无需循环:
complete
结果:
import xml.etree.ElementTree as ET
data = """
<root>
<c1>
<c2>C2 Value 1</c2>
<s1>
<s2> S2 Value 1</s2>
<p1>
<p2>P2 Value 1</p2>
</p1>
<p1>
<p2>P2 Value 2</p2>
</p1>
</s1>
<s1>
<s2> S2 Value 2</s2>
<p1>
<p2>P2 Value 3</p2>
</p1>
</s1>
</c1>
</root>
"""
doc = ET.fromstring(data)
print ','.join(doc.findtext(_) for _ in ['.//c2', './/c2/../s1/s2', './/c2/../s1/p1/p2'])
+1在另一篇推荐lxml的帖子上,如果你需要更高级的东西,可以提供更好的xpath支持。