Преобразование сложных XML в CSV - PullRequest
0 голосов
/ 14 июля 2020

У меня есть XML с такой структурой:

<result>
    <report>
        <id>111</id>
        <user>username1</user>
        <actions_list>
            <action1>
                <id>a_1</id>
            </action1>
            <action1>
                <id>a_2</id>
            </action1>
            <action1>
                <id>a_3</id>
            </action1>
        </actions_list>
    </report>

    <report>
        <id>222</id>
        <user>username2</user>
        <actions_list>
            <action1>
                <id>a_1</id>
            </action1>
            <action2>
                <id>a_2</id>
            </action2>
            <action3>
                <id>a_3</id>
            </action3>
            <action4>
                <id>a_4</id>
            </action4>
            <action5>
                <id>a_5</id>
            </action5>
        <actions_list>
    </report>
</result>

Итак, я хочу создать файл CSV с такой структурой:

+---+-----+-----------+-----+
| 1 | 111 | username1 | a_1 |
+---+-----+-----------+-----+
| 1 | 111 | username1 | a_2 |
+---+-----+-----------+-----+
| 1 | 111 | username1 | a_3 |
+---+-----+-----------+-----+
| 2 | 222 | username2 | a_1 |
+---+-----+-----------+-----+
| 2 | 222 | username2 | a_2 |
+---+-----+-----------+-----+
| 2 | 222 | username2 | a_3 |
+---+-----+-----------+-----+
| 2 | 222 | username2 | a_4 |
+---+-----+-----------+-----+
| 2 | 222 | username2 | a_5 |
+---+-----+-----------+-----+

Я пытался используйте python BeautifulSoup и xml .etree, но не можете обрабатывать поля с одинаковым именем ('id' в моем примере) и разным количеством действий в разных отчетах. Как мне это сделать? Любая помощь приветствуется. Заранее спасибо.

1 Ответ

0 голосов
/ 14 июля 2020

Попробуйте следующее:

import xml.etree.ElementTree as ET
import csv

with open("yourfile.csv) as f:
    writer = csv.writer(f)

    # Use either of the next two lines, depending on whether you're reading from a 
file
    root = ET.fromstring(your_xml_str)
    root = ET.parse("user_actions.xml")
    
    for reportIndex, report in enumerate(root, start=1):
        id = report.find("id").text
        user = report.find("user").text
        actions_list = report.find("actions_list")
        
        for action in actions_list:
            action_id = action.find("id").text
            writer.writerow([reportIndex, id, user, action_id])
        
        


...