【问题标题】:ElementTree Python: How to extract siblings if siblings are nested?ElementTree Python:如果兄弟姐妹嵌套,如何提取兄弟姐妹?
【发布时间】:2019-08-29 02:04:41
【问题描述】:

我有一个要转换为 Excel 数据集的 XML 文件。 XML 是这样排列的:

<XML Data>
    <Record>
        <ID>
            <Client id="01"></Client>
        </ID>
        <Service>
            <Product id="A"></Product>
            <Product id="B"></Product>
            <Product id="C"></Product>
        </Service>
    </Record>
    <Record>
        <ID>
            <Client id="02"></Client>
        </ID>
        <Service>
            <Product id="A"></Product>
            <Product id="B"></Product>
            <Product id="Y"></Product>
        </Service>
    </Record>
    <Record>
        <ID>
            <Client id="24"></Client>
        </ID>
        <Service>
            <Product id="U"></Product>
        </Service>
    </Record>
</XML Data>

如您所见,每条记录都显示了具有多个服务的单个客户端。

我正在尝试仅使用 ElementTree 来完成这项工作。这是为每个客户端 ID 返回所有服务的错误代码——我不知道如何让它返回客户端实际拥有的每个服务:

for x in root.findall("Record/ID/Client"):
    client = x.get("id")
    for y in root.findall('.//Service/Product'):
        service = y.get("id")
        print(client, service)

我正在尝试以 CSV 格式将其排列成这样:

ClientID    ServiceID
01          A
01          B
01          C
02          A
02          B
02          Y
24          U

任何建议将不胜感激!我查过这个,但只能找到显示如何提取实际兄弟姐妹的资源——因为客户端 ID 和服务 ID 是我要提取的孩子的父母,这证明有点混乱。谢谢!

【问题讨论】:

  • 在第二个 for 循环中,尝试将 root.findall 更改为 x.findall。这样,xpath 就相对于当前的x
  • 这样做导致第二个循环根本没有输出,所以似乎不是这样。
  • 糟糕,抱歉。出于某种原因,我认为您首先选择了Record 而不是Client。请在下面查看我的答案。

标签: xml python-3.x xml-parsing elementtree


【解决方案1】:

先选择Record,而不是先选择Client

然后您的第二个 for 循环可以从 root.finall 更改为 x.findall 只会找到当前 RecordProduct 元素。

示例...

XML 输入(test.xml;修复无效的根元素)

<XML_Data>
    <Record>
        <ID>
            <Client id="01"></Client>
        </ID>
        <Service>
            <Product id="A"></Product>
            <Product id="B"></Product>
            <Product id="C"></Product>
        </Service>
    </Record>
    <Record>
        <ID>
            <Client id="02"></Client>
        </ID>
        <Service>
            <Product id="A"></Product>
            <Product id="B"></Product>
            <Product id="Y"></Product>
        </Service>
    </Record>
    <Record>
        <ID>
            <Client id="24"></Client>
        </ID>
        <Service>
            <Product id="U"></Product>
        </Service>
    </Record>
</XML_Data>

Python

import xml.etree.ElementTree as ET

tree = ET.parse('test.xml')

root = tree.getroot()

for x in root.findall("Record"):
    client = x.find("ID/Client").get("id")
    for y in x.findall('.//Service/Product'):
        service = y.get("id")
        print(client, service)

打印输出

01 A
01 B
01 C
02 A
02 B
02 Y
24 U

【讨论】:

  • 天哪,这么简单的解决方法!非常感谢——我尝试了近 20 种不同的方法,结果我需要做的就是从更高的层次开始!
猜你喜欢
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-06
  • 2014-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多