python lxml - 如何获取 XML 中子元素的值

python lxml - how to get the value of a subelement in XML

XML:

<tree>
  <row>
     <a>This is a</a>
     <b>This is b</b>
  </row>
</tree>

所以我在网上看到了很多解决方案,并且已经查找了其中的许多解决方案。以下对我不起作用:

tree = etree.XML('file.xml')
print tree[0].findtext('a'). // None
print tree[0].find('a'). // None
print tree[0].xpath('a') // None
print tree[0].xpath('/a') //None
print tree[0].xpath('//a') //None
print tree[0].xpath('/a') //None
print tree.xpath('//row/a') //None
print tree.xpath('//row/a/text()') //None

我找到的唯一方法就像做 tree[0][0].text 但是我的实际 XML 包含 25 个子元素,执行 25 次并不是真正干净的代码..

也许你们知道我做错了什么?

我也知道有类似 BeautifulSoup 的东西,但经过测试后,我得出结论,由于性能原因,这不适合我的情况.. (benchmark here)

谢谢!

您可以使用 .iterfor 循环。

for row_node in tree.iter('row'):
    a_node = row_node.find('a')
    b_node = row_node.find('b')
    print(a_node.text)
    print(b_node.text)

# This is a
# This is b

所以我终于想通了我的问题。这是 xml 的名称间距。 我没有用它做任何事情,所以我觉得没必要看。

XML略有不同:

<tree xmlns="http://www.schemas.net/schema/MyXMLSchema">
  <row>
     <a>This is a</a>
     <b>This is b</b>
  </row>
</tree>

所以我需要在查找中做的是添加命名空间。 为了动态地做到这一点,我使用了 answer from an other question 像这样:

tree = etree.XML('file.xml')
namespace = tree.xpath('namespace-uri(.)')
for row in tree:
    print row.findtext('{%s}a' % namespace)
    print row.findtext('{%s}b' % namespace)

# This is a
# This is b

如果关心的不仅仅是包含行,tree.iter('row') 确实如 DeepSpace 指出的那样,是一个更好的结果。