ElementTree Python: Как извлечь братьев и сестер, если братья и сестры вложены? - PullRequest
1 голос
/ 08 апреля 2019

У меня есть XML-файл, который я пытаюсь преобразовать в набор данных Excel. 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. Это неправильный код, который возвращает ВСЕ службы для каждого идентификатора клиента - я не могу понять, как заставить его возвращать все службы, которые фактически имел клиент:

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

Любой совет будет принята с благодарностью! Я посмотрел это, но смог найти только ресурсы, которые показывают, как извлечь фактических братьев и сестер - поскольку идентификатор клиента и идентификатор службы являются родителями для детей, которых я хочу извлечь, это немного сбивает с толку. Спасибо!

1 Ответ

2 голосов
/ 08 апреля 2019

Вместо первого выбора Client, сначала выберите Record.

Тогда ваш второй цикл for может быть изменен с root.finall на x.findall, он найдет только Product элементов для текущего Record.

Пример ...

Ввод 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
...