【问题标题】:Reading XML same name sub-element python读取XML同名子元素python
【发布时间】:2019-10-10 10:18:35
【问题描述】:

我也是 XML 解析和 python 的新手。我需要找到树子元素并打印所有子元素。

我有一个这样的 XML 文件。这是我的文件- https://gofile.io/?c=OXcdue

  • 分配 - 队列 ---队列的子元素 ---队列(子元素) ----这个队列的子元素 - - 队列 ----队列

我的要求是读取所有具有子队列及其子队列的队列。

【问题讨论】:

  • 我只想打印队列 pireporting_q1- "所有属性和子元素"+ "atscale_rtam_mr_sq1" 和所有子元素+ "atscale_spark_sq1" 和所有子元素- 想要的结果在这里 - 6960000 mb,1160 vcores,87 个磁盘10440000 mb,1740 个 vcores,130 个磁盘
  • 请编辑问题以阐明您想要什么。评论很难阅读。添加他的 XML 文件的内容。
  • 请检查链接中的文件。它不允许我在这里添加文件。这是我的第一篇文章。让我知道如何在这里添加我的代码而不会给我错误。

标签: python xml xml-parsing


【解决方案1】:

您可以使用lxml 库来解析任何xml 内容。这个库比标准的xml 库更好,因为它允许您在必要时获取 xml 文档的命名空间(在您的情况下不需要)。

from lxml import etree
tree = etree.parse(path_to_xml_file)
root = tree.getroot()

for children in root.getchildren():
    print (children.tag)

    for child in children:
        print(child.tag, child.text)

请参阅文档here,了解有关如何访问 xml 文件的各个部分并递归查找所有子元素的更多信息。此文档适用于标准 xml 库,但也受 lxml 库支持因为lxml 是建立在xml 之上的。

【讨论】:

  • xml 中的命名空间是一种将元素和属性分配给组的方式。这允许您拥有具有相同名称的元素,但避免冲突,因为它们被分配到不同的组。命名空间是在 xml 的顶部定义的,如下所示: 如果您尝试使用普通的 xml 库解析它,它将找不到命名空间,而 lxml 有一个方法可以做到这一点。
  • 只是想给出一个使用 lxml 而不是 xml 的理由。
  • 根据我的经验,xml 库不能很好地处理命名空间,尤其是在命名空间为 None 的情况下。
【解决方案2】:

如下(不使用外部库)

import pprint
import xml.etree.ElementTree as ET

xml = '''<allocations>
    <queue name="bdpaas_express_q1">
      <minResources>12000 mb,2 vcores,1 disks</minResources>
      <maxResources>18000 mb,3 vcores,2 disks</maxResources>
      <aclSubmitApps> xyz</aclSubmitApps>
      <aclAdministerApps> xyz</aclAdministerApps>
      <label>allnodes</label>
    </queue>
    <queue name="dl_priority_q1">
      <minResources>8496000 mb,1416 vcores,108 disks</minResources>
      <maxResources>12768000 mb,2128 vcores,162 disks</maxResources>
      <aclSubmitApps> dla_grp</aclSubmitApps>
      <aclAdministerApps> dla_grp</aclAdministerApps>>
      <label>fastnodes</label>
    </queue>
    <queue name="pireporting_q1">
      <minResources>6960000 mb,1160 vcores,87 disks</minResources>
      <maxResources>10440000 mb,1740 vcores,130 disks</maxResources>
      <queue name="atscale_rtam_mr_sq1">
        <minResources>6000000 mb,1000 vcores,75 disks</minResources>
        <maxResources>9000000 mb,1500 vcores,112 disks</maxResources>
        <aclSubmitApps> atscalep</aclSubmitApps>
        <aclAdministerApps> atscalep</aclAdministerApps>
        <label>allnodes</label>
      </queue>
      <queue name="atscale_spark_sq1">
        <minResources>960000 mb,160 vcores,12 disks</minResources>
        <maxResources>1440000 mb,240 vcores,18 disks</maxResources>
        <aclSubmitApps> atscalep</aclSubmitApps>
        <aclAdministerApps> atscalep</aclAdministerApps>
        <label>allnodes</label>
      </queue>
    </queue>
  <queuePlacementPolicy>
    <rule create="false" name="specified" />
    <rule name="reject" />
  </queuePlacementPolicy>
</allocations>
'''


root = ET.fromstring(xml)
queues = root.findall('.//queue')
for queue in queues:
  if queue.find('./queue'):
    print(ET.tostring(queue, encoding='utf8', method='xml'))

输出

<?xml version="1.0" encoding="UTF-8"?>
<queue name="pireporting_q1">
   <minResources>6960000 mb,1160 vcores,87 disks</minResources>
   <maxResources>10440000 mb,1740 vcores,130 disks</maxResources>
   <queue name="atscale_rtam_mr_sq1" />
   <queue name="atscale_spark_sq1" />
</queue>

【讨论】:

  • 嗨,我有一个非常大的 XML 文件,这只是我给出的一个例子。除了字符串方法,我还有什么选择?
  • fromstring 只是为了回答。您可以使用“解析”
  • 你能告诉我如何在这里分别迭代父队列和子队列标签吗?感谢您的帮助....
  • @user2910022 我不确定我是否理解。我的代码是否解决了您的问题并且您得到了您正在寻找的输出?您还在寻找什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
相关资源
最近更新 更多