【问题标题】:Heavily nested XML to CSV using Python使用 Python 将 XML 大量嵌套到 CSV
【发布时间】:2018-09-03 13:25:04
【问题描述】:

我有以下 XML 文件,我想使用 Python 将其转换为 CSV。

<?xml version="1.0" encoding="UTF-8"?><households xmlns:s="http://www.mediametrie.fr/nge/  " xmlns:xalan="http://xml.apache.org/xalan" date="2015-04-06" creation_date="2015-04-08T03:48:34">
    <household id="10003456">
        <destinations/>
        <members>
            <member id="1">
                <member_process result="KO" vacation="undefined">
                    <individual_audience>
                        <individual_audience_tvset id="1">
                            <channel session="5647128" begin="56435" end="76896"/>
                        </individual_audience_tvset>
                    </individual_audience>
                    <alarms>
                        <alarm id="Alarm_id_1" rule_id="Rule_id_1">
                            <parameters>
                                <parameter name="tvset_id" value="1"/>
                                <parameter name="length" value="46384"/>
                                <parameter name="end" value="2017-04-06T20:30:00"/>
                                <parameter name="channel" value="1010128"/>
                            </parameters>
                        </alarm>
                    </alarms>
                </member_process>
            </member>
            <member id="2">
                <member_process result="KO" vacation="undefined">
                    <individual_audience>
                        <individual_audience_tvset id="1">
                            <channel session="5674897" begin="98765" end="76543"/>
                        </individual_audience_tvset>
                    </individual_audience>
                    <alarms>
                        <alarm id="Alarm_id_2" rule_id="Rule_id_2">
                            <parameters>
                                <parameter name="tvset_id" value="1"/>
                                <parameter name="length" value="56745"/>
                                <parameter name="end" value="2017-04-06T20:30:00"/>
                                <parameter name="channel" value="4563256"/>
                            </parameters>
                        </alarm>
                    </alarms>
                </member_process>
            </member>
            <member id="3">
                <member_process result="KO" vacation="undefined">
                    <individual_audience>
                        <individual_audience_tvset id="1">
                            <channel session="1010128" begin="47218" end="93600"/>
                        </individual_audience_tvset>
                    </individual_audience>
                    <alarms>
                        <alarm id="AL_R_INDP_AUDIENCE_TOO_HIGH_LIMIT" rule_id="R_INDP_AUDIENCE_TOO_HIGH_LIMIT">
                            <parameters>
                                <parameter name="tvset_id" value="1"/>
                                <parameter name="length" value="46382"/>
                                <parameter name="end" value="2015-04-06T20:30:00"/>
                                <parameter name="channel" value="1010128"/>
                            </parameters>
                        </alarm>
                    </alarms>
                </member_process>
            </member>
            <member id="4">
                <member_process result="KO" vacation="undefined">
                    <individual_audience>
                        <individual_audience_tvset id="1">
                            <channel session="1010128" begin="47219" end="93600"/>
                        </individual_audience_tvset>
                    </individual_audience>
                    <alarms>
                        <alarm id="AL_R_INDP_AUDIENCE_TOO_HIGH_LIMIT" rule_id="R_INDP_AUDIENCE_TOO_HIGH_LIMIT">
                            <parameters>
                                <parameter name="tvset_id" value="1"/>
                                <parameter name="length" value="46381"/>
                                <parameter name="end" value="2015-04-06T20:30:00"/>
                                <parameter name="channel" value="1010128"/>
                            </parameters>
                        </alarm>
                    </alarms>
                </member_process>
            </member>
            <member id="5">
                <member_process result="KO" vacation="undefined">
                    <individual_audience>
                        <individual_audience_tvset id="1">
                            <channel session="1010128" begin="47220" end="93600"/>
                        </individual_audience_tvset>
                    </individual_audience>
                    <alarms>
                        <alarm id="AL_R_INDP_AUDIENCE_TOO_HIGH_LIMIT" rule_id="R_INDP_AUDIENCE_TOO_HIGH_LIMIT">
                            <parameters>
                                <parameter name="tvset_id" value="1"/>
                                <parameter name="length" value="46380"/>
                                <parameter name="end" value="2015-04-06T20:30:00"/>
                                <parameter name="channel" value="1010128"/>
                            </parameters>
                        </alarm>
                    </alarms>
                </member_process>
            </member>
            <member id="6">
                <member_process result="KO" vacation="undefined">
                    <individual_audience>
                        <individual_audience_tvset id="1">
                            <channel session="1010128" begin="47221" end="93600"/>
                        </individual_audience_tvset>
                    </individual_audience>
                    <alarms>
                        <alarm id="AL_R_INDP_AUDIENCE_TOO_HIGH_LIMIT" rule_id="R_INDP_AUDIENCE_TOO_HIGH_LIMIT">
                            <parameters>
                                <parameter name="tvset_id" value="1"/>
                                <parameter name="length" value="46379"/>
                                <parameter name="end" value="2015-04-06T20:30:00"/>
                                <parameter name="channel" value="1010128"/>
                            </parameters>
                        </alarm>
                    </alarms>
                </member_process>
            </member>
        </members>
        <regular_guests/>
        <occasional_guests/>
        <tvsets>
            <tvset id="1">
                <tvset_process result="OK">
                    <tvset_audience>
                        <channel session="47" begin="46304" end="46384"/>
                        <channel session="1010483" begin="46384" end="46419"/>
                        <channel session="235" begin="46419" end="46424"/>
                        <channel session="1010128" begin="46424" end="93600"/>
                    </tvset_audience>
                    <alarms>
                        <alarm id="AL_T_P_VALID_LAST_HOUR_REBOOT" rule_id="T_P_METER_STOPPING_TIMESTAMPING">
                            <parameters>
                                <parameter name="unique_id" value="4547"/>
                                <parameter name="reboot_date" value="2015-04-06T07:17:44"/>
                                <parameter name="length" value="1.6221180555555557"/>
                            </parameters>
                        </alarm>
                        <alarm id="AL_T_P_VALID_LAST_HOUR_REBOOT" rule_id="T_P_METER_STOPPING_TIMESTAMPING">
                            <parameters>
                                <parameter name="unique_id" value="4566"/>
                                <parameter name="reboot_date" value="2015-04-07T13:17:54"/>
                                <parameter name="length" value="1.2313657407407406"/>
                            </parameters>
                        </alarm>
                        <alarm id="AL_T_P_TECH_ID_RESOL_FALSE_POSITIVE" rule_id="T_P_TECH_ID_RESOL">
                            <parameters>
                                <parameter name="channel_id" value="194"/>
                                <parameter name="unique_id" value="4549"/>
                            </parameters>
                        </alarm>
                    </alarms>
                </tvset_process>
            </tvset>
        </tvsets>
        <household_process result="KO" vacation="no">
            <alarms>
                <alarm id="AL_T_FP_AUDIENCE_WITHOUT_PRESENCE" rule_id="T_FP_AUDIENCE_WITHOUT_PRESENCE">
                    <parameters>
                        <parameter name="tvset_id" value="1"/>
                        <parameter name="length" value="80"/>
                        <parameter name="start" value="2015-04-06T07:21:44"/>
                    </parameters>
                </alarm>
                <alarm id="AL_T_FP_AUDIENCE_WITHOUT_PRESENCE" rule_id="T_FP_AUDIENCE_WITHOUT_PRESENCE">
                    <parameters>
                        <parameter name="tvset_id" value="1"/>
                        <parameter name="length" value="792"/>
                        <parameter name="start" value="2015-04-06T07:23:44"/>
                    </parameters>
                </alarm>
                <alarm id="AL_R_FP_AUDIENCE_TOO_HIGH_LIMIT" rule_id="R_FP_AUDIENCE_TOO_HIGH_LIMIT">
                    <parameters>
                        <parameter name="tvset_id" value="1"/>
                        <parameter name="length" value="47176"/>
                        <parameter name="end" value="2015-04-06T20:30:00"/>
                        <parameter name="channel" value="1010128"/>
                    </parameters>
                </alarm>
                <alarm id="AL_R_FP_AT_LEAST_ONE_MEMBER_OK" rule_id="R_FP_AT_LEAST_ONE_MEMBER_OK">
                    <parameters/>
                </alarm>
            </alarms>
        </household_process>
    </household>
</households>

输出应该是这样的

household id, destinations, member id, result, vacation, individual_audience_tvset id, session, begin, end, alarm id, rule_id, name, value
10003456, None, 1, KO, undefined, 1, 5647128, 56435, 76896, Alarm_id_1, Rule_id_1, tvset_id, 1
10003456, None, 1, KO, undefined, 1, 5647128, 56435, 76896, Alarm_id_1, Rule_id_1, length, 46384
10003456, None, 1, KO, undefined, 1, 5647128, 56435, 76896, Alarm_id_1, Rule_id_1, end, 2017-04-06T20:30:00
10003456, None, 1, KO, undefined, 1, 5647128, 56435, 76896, Alarm_id_1, Rule_id_1, channel, 1010128

对于成员 id = 2 具有相同的家庭 id。

非常感谢任何帮助。 提前谢谢!

【问题讨论】:

  • 使用 Beautiful Soup 解析 XML 和标准库来写出 CSV。
  • 您确定自己尝试过?
  • 是的,我试过了,常规的 for 循环,但它打印出意外的嵌套 XML 结果。
  • 您能否使用您尝试过的代码更新您的问题,以便我们可以在您已有的基础上进行构建?
  • 蒂姆是对的。上传您的代码。

标签: python xml csv beautifulsoup lxml


【解决方案1】:

这假设您将 XML 保存在一个名为 input.xml 的文件中。 BeautifulSoup 可用于帮助解析从文件中读取的 XML。然后,您只需要创建一个包含您希望提取的所有信息的表:

from bs4 import BeautifulSoup
import csv

fields = [
    "household id",
    "destinations",
    "member id"]

member_fields = [    
    ["result", "member_process", "result"],
    ["vacation", "member_process", "vacation"],
    ["individual_audience_tvset id", "individual_audience_tvset", "id"],
    ["session", "channel", "session"],
    ["begin", "channel", "begin"],
    ["end", "channel", "end"],
    ["alarm id", "alarm", "id"],
    ["rule_id", "alarm", "rule_id"],
    ["name", "parameter", "name"],
    ["value", "parameter", "value"]
    ]

fieldnames = fields + [field for field, _, _ in member_fields]    

with open('input.xml') as f_input, open('output.csv', 'w', newline='') as f_output:
    csv_output = csv.DictWriter(f_output, fieldnames=fieldnames)
    csv_output.writeheader()

    xml = f_input.read()
    soup = BeautifulSoup(xml, "xml")
    household_id = soup.find('household')['id']

    for member in soup.find_all('member'):
        member_id = member['id']
        row = {'household id' : household_id, 'member id' : member_id}

        for field, x, y in member_fields:
            row[field] = member.find(x)[y]

        csv_output.writerow(row)

这将创建 output.csv 包含:

household id,destinations,member id,result,vacation,individual_audience_tvset id,session,begin,end,alarm id,rule_id,name,value
10003456,,1,KO,undefined,1,5647128,56435,76896,Alarm_id_1,Rule_id_1,tvset_id,1
10003456,,2,KO,undefined,1,5674897,98765,76543,Alarm_id_2,Rule_id_2,tvset_id,1
10003456,,3,KO,undefined,1,1010128,47218,93600,AL_R_INDP_AUDIENCE_TOO_HIGH_LIMIT,R_INDP_AUDIENCE_TOO_HIGH_LIMIT,tvset_id,1
10003456,,4,KO,undefined,1,1010128,47219,93600,AL_R_INDP_AUDIENCE_TOO_HIGH_LIMIT,R_INDP_AUDIENCE_TOO_HIGH_LIMIT,tvset_id,1
10003456,,5,KO,undefined,1,1010128,47220,93600,AL_R_INDP_AUDIENCE_TOO_HIGH_LIMIT,R_INDP_AUDIENCE_TOO_HIGH_LIMIT,tvset_id,1
10003456,,6,KO,undefined,1,1010128,47221,93600,AL_R_INDP_AUDIENCE_TOO_HIGH_LIMIT,R_INDP_AUDIENCE_TOO_HIGH_LIMIT,tvset_id,1

【讨论】:

  • 非常好的回答。我试图将您的问题实施到我的 xml 文件中,但即使我的 xml 相似,直到现在都没有成功。如果你有时间请看一下我的xml文件stackoverflow.com/questions/59009797/…
  • 这仍然是一个很好的解决方案。在过去的几天里,我搜索了堆栈,这是复杂嵌套 XML 的最简单解决方案
猜你喜欢
  • 1970-01-01
  • 2018-08-29
  • 2021-09-17
  • 2016-04-26
  • 2021-05-07
  • 1970-01-01
  • 2020-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多