在 ElementTree 中检查 XML 元素是否有子元素

新手上路,请多包涵

我以这种方式检索 XML 文档:

 import xml.etree.ElementTree as ET

root = ET.parse(urllib2.urlopen(url))
for child in root.findall("item"):
  a1 = child[0].text # ok
  a2 = child[1].text # ok
  a3 = child[2].text # ok
  a4 = child[3].text # BOOM
  # ...

XML 如下所示:

 <item>
  <a1>value1</a1>
  <a2>value2</a2>
  <a3>value3</a3>
  <a4>
    <a11>value222</a11>
    <a22>value22</a22>
  </a4>
</item>

我如何检查 a4 (在这种特殊情况下,但它可能是任何其他元素)是否有孩子?

原文由 Incerteza 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

您可以在元素上尝试 list 函数:

 >>> xml = """<item>
  <a1>value1</a1>
  <a2>value2</a2>
  <a3>value3</a3>
  <a4>
    <a11>value222</a11>
    <a22>value22</a22>
  </a4>
</item>"""
>>> root = ET.fromstring(xml)
>>> list(root[0])
[]
>>> list(root[3])
[<Element 'a11' at 0x2321e10>, <Element 'a22' at 0x2321e48>]
>>> len(list(root[3]))
2
>>> print "has children" if len(list(root[3])) else "no child"
has children
>>> print "has children" if len(list(root[2])) else "no child"
no child
>>> # Or simpler, without a call to list within len, it also works:
>>> print "has children" if len(root[3]) else "no child"
has children

我修改了你的示例,因为 findall 函数调用 item root 没有工作(因为 findall 将搜索当前元素)。如果你想在你的工作程序中访问子子的文本,你可以这样做:

 for child in root.findall("item"):
  # if there are children, get their text content as well.
  if len(child):
    for subchild in child:
      subchild.text
  # else just get the current child text.
  else:
    child.text

不过,这很适合递归。

原文由 jlr 发布,翻译遵循 CC BY-SA 3.0 许可协议

我能找到的最简单的方法是直接使用元素的 bool 值。这意味着您可以按原样在条件语句中使用 a4

 a4 = Element('a4')
if a4:
    print('Has kids')
else:
    print('No kids yet')

a4.append(Element('x'))
if a4:
    print('Has kids now')
else:
    print('Still no kids')

运行此代码将打印

No kids yet
Has kids now

元素的布尔值不会说明 text , tail 或属性。它只表明孩子的存在或不存在,这是最初的问题所问的。

原文由 Mad Physicist 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题