【问题标题】:Python - Converting xml to csv using Python pandasPython - 使用 Python pandas 将 xml 转换为 csv
【发布时间】:2019-07-27 19:37:08
【问题描述】:

我是新来的,我一直在尝试创建一个小的 python 脚本来将 xml 转换为 csv。根据我在 Stackoverflow 中阅读的各种帖子,我设法提出了一个可以正常工作的示例代码。但是我尝试使用的数据有多个层次,因此我不确定如何在叶子上提取数据级别。

下面是数据的样子:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Transmission>
    <TransmissionBody>
        <level1>
            <level2>
                <level3>
                    <level4>
                        <level5>
                            <level6>
                                <ColA>ABC</ColA>
                                <ColB>123</ColB>
                            </level6>
                        </level5>
                    </level4>
                </level3>
            </level2>
        </level1>
    </TransmissionBody>
</Transmission>

我正在尝试使用下面的代码来尝试将 xml 转换为 csv

import pandas as pd
import xml.etree.ElementTree as ET

tree = ET.parse('file.xml')
root = tree.getroot()
final = {}
for elem in root:
    if len(elem):
        for c in elem.getchildren():
            final[c.tag] = c.text
    else:
        final[elem.tag] = elem.text

df = pd.DataFrame([final])
df.to_csv('file.csv)

然而,此代码只是从 level2 中提取 level2 而不是从 level6 中提取 ColA。

预期输出:

Transmission,TransmissionBody,level1,level2,level3,level4,level5,level6,ColA,ColB
,,,,,,,,ABC,123
,,,,,,,,DEF,456

更新代码:

allFiles = glob.glob(folder)
for file in allFiles:
    xmllist = [file]
    for xmlfile in xmllist:
        tree = ET.parse(xmlfile)
        root = tree.getroot()

        def f(elem, result):
            result[elem.tag] = elem.text
            cs = elem.getchildren()
            for c in cs:
                result = f(c, result)
            return result

         d = f(root, {})
         df = pd.DataFrame(d, index=['values'])

【问题讨论】:

    标签: python xml pandas export-to-csv


    【解决方案1】:

    你有一个缩进问题

    if len(elem):
    

    我想这应该可以解决它。

    【讨论】:

    • if len(elem): 在基线上,你建议在那条线上使用什么样的缩进?
    • 是什么让您认为 if () 行在基线上?对我来说,它看起来是 for elem in root: 循环的一部分,所以应该缩进。
    【解决方案2】:

    如果我正确理解了您的问题,您需要遍历 XML 树,因此您可能希望有一个递归函数来执行此操作。类似于以下内容:

    import pandas as pd
    import xml.etree.ElementTree as ET
    
    tree = ET.parse('file.xml')
    root = tree.getroot()
    
    def f(elem, result):
        result[elem.tag] = elem.text
        cs = elem.getchildren()
        for c in cs:
            result = f(c, result)
        return result
    
    d = f(root, {})
    df = pd.DataFrame(d, index=['values']).T
    df
    

    输出:

        values
    Transmission    \n
    TransmissionBody    \n
    level1  \n
    level2  \n
    level3  \n
    level4  \n
    level5  \n
    level6  \n
    ColA    ABC
    ColB    123
    

    更新: 这是我们需要对多个 XML 文件执行此操作的时候。我添加了另一个与原始文件类似的文件,其中 ColA、ColB 行替换为

    <ColA>DEF</ColA>
    <ColB>456</ColD>
    

    代码如下:

    def f(elem, result):
        result[elem.tag] = elem.text
        cs = elem.getchildren()
        for c in cs:
            result = f(c, result)
        return result
    
    result = {}
    for file in glob.glob('*.xml'):
        tree = ET.parse(file)
        root = tree.getroot()
        result = f(root, result)
    
    df = pd.DataFrame(result, index=['values']).T
    df
    

    还有输出:

                        0    1
    Transmission       \n   \n
    TransmissionBody   \n   \n
    level1             \n   \n
    level2             \n   \n
    level3             \n   \n
    level4             \n   \n
    level5             \n   \n
    level6             \n   \n
    ColA              ABC  DEF
    ColB              123  456
    

    【讨论】:

    • 一个疑问:你为什么要转置它?要求是在顶行创建一个带有标题的 csv,这与第一列的标题不同,不是吗?
    猜你喜欢
    • 2021-12-26
    • 2017-09-16
    • 2016-12-21
    • 1970-01-01
    • 2017-09-12
    • 2016-10-03
    • 2019-03-15
    • 1970-01-01
    相关资源
    最近更新 更多