【问题标题】:Python Parsing nested XML and flattening the dataPython解析嵌套XML并展平数据
【发布时间】:2013-01-15 02:02:48
【问题描述】:

我正在尝试将以下 XML 数据扁平化为 CSV 类型的表数据。

我可以获取 Sal 元素及其属性中的数据,但我无法将 SalC 数据展平到父航行属性以生成平面表数据。

我想在 XML 数据下方展平,以便我可以写入数据库进行进一步处理。

col1, col2, col3, col4, col5, col6, col6, col7, col8, col9, col10

XML 数据:

<Sal col1="a1" col2="C" col3="12/5/2012" col4="a" col5="8" col6="True">
    <SalC col7="A" col8="1" col9="2" col10="True"/>
    <SalC col7="A1" col8="1" col9="2" col10="False"/>
    <SalC col7="B" col8="1" col9="2" col10="False"/>
    <SalC col7="C" col8="1" col9="2" col10="False"/>
    <SalC col7="D" col8="1" col9="2" col10="False"/>
    <SalC col7="E" col8="1" col9="2" col10="False"/>
    <SalC col7="E1" col8="1" col9="2" col10="False"/>
    <SalC col7="F" col8="1" col9="2" col10="False"/>
</Sal>
<Sal col1="a1" col2="C" col3="12/9/2012" col4="b" col5="8" col6="True">
    <SalC col7="A" col8="1" col9="2" col10="False"/>
    <SalC col7="B" col8="1" col9="2" col10="False"/>
    <SalC col7="C" col8="1" col9="2" col10="True"/>
    <SalC col7="D" col8="1" col9="2" col10="False"/>
    <SalC col7="E" col8="1" col9="2" col10="False"/>
</Sal>
<Sal col1="a2" col2="C" col3="12/8/2012" col4="c" col5="15" col6="True">
    <SalC col7="A" col8="1" col9="2" col10="True"/>
    <SalC col7="A1" col8="1" col9="2" col10="False"/>
    <SalC col7="B" col8="1" col9="2" col10="False"/>
    <SalC col7="C" col8="1" col9="2" col10="True"/>
    <SalC col7="D" col8="1" col9="2" col10="False"/>
    <SalC col7="E" col8="1" col9="2" col10="False"/>
    <SalC col7="E1" col8="1" col9="2" col10="True"/>
    <SalC col7="F" col8="1" col9="2" col10="False"/>
</Sal>
<Sal col1="a3" col2="C" col3="12/9/2012" col4="d" col5="8" col6="True">
    <SalC col7="A" col8="1" col9="2" col10="False"/>
    <SalC col7="B" col8="1" col9="2" col10="False"/>
    <SalC col7="C" col8="1" col9="2" col10="False"/>
    <SalC col7="D" col8="1" col9="2" col10="True"/>
    <SalC col7="E" col8="1" col9="2" col10="False"/>
</Sal>

感谢您的帮助。

【问题讨论】:

  • 你试过beautifullsoup吗??

标签: python xml xml-parsing python-2.7 lxml


【解决方案1】:

这可以使用 XSLT 轻松解决,而无需在工作流程中引入 Python,但是,如果您必须使用 Python,lxml.etree 方便地引入了一个新类 lxml.etree.XSLT,您可以利用它来发挥自己的优势。

假设您的 XML 数据位于名为 xmlfile.xml 的文件中,那么下面的代码应该可以工作。

xsltfile.xsl

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="text" />
        <xsl:template match="SalC">
                <xsl:value-of select="concat(../@col1,',', ../@col2,',',../@col3,',',../@col4,',',../@col5,',',../@col6,',',@col7,',',@col8,',',@col9,',',@col10)" />
        </xsl:template>
</xsl:stylesheet>

示例代码

from lxml import etree

xsltfile = etree.XSLT(etree.parse('xsltfile.xsl'))
xmlfile = etree.parse('xmlfile.xml')
output = xsltfile(xmlfile)
print(output)

【讨论】:

    【解决方案2】:

    sal.attrib 类似于字典:

    row = dict(sal.attrib)
    

    salc.attrib 也类似于 dict。要“扁平化”——或者更确切地说,加入——这两个字典,你可以使用dict.update

    row.update(salc.attrib)
    

    假设每个SalC 元素都有col7col8cal9col10 属性,您可以为sal 中的每个salc 调用row.update(salc.attrib)


    import lxml.etree as ET
    import csv
    
    text = '''\
    <root>
    <Sal col1="a1" col2="C" col3="12/5/2012" col4="a" col5="8" col6="True">
        <SalC col7="A" col8="1" col9="2" col10="True"/>
    ...
        <SalC col7="D" col8="1" col9="2" col10="True"/>
        <SalC col7="E" col8="1" col9="2" col10="False"/>
    </Sal>
    </root>'''
    
    fieldnames = ('col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col6', 'col7', 'col8', 
                  'col9', 'col10')
    
    with open('/tmp/output.csv', 'wb') as f:
        writer = csv.DictWriter(f, fieldnames, delimiter = ',', lineterminator = '\n', )
        writer.writeheader()
        root = ET.fromstring(text)
        for sal in root.xpath('//Sal'):
            row = dict(sal.attrib)
            for salc in sal:
                row.update(salc.attrib)
                writer.writerow(row)
    

    产量

    col1,col2,col3,col4,col5,col6,col6,col7,col8,col9,col10
    a1,C,12/5/2012,a,8,True,True,A,1,2,True
    a1,C,12/5/2012,a,8,True,True,A1,1,2,False
    a1,C,12/5/2012,a,8,True,True,B,1,2,False
    ...
    a3,C,12/9/2012,d,8,True,True,B,1,2,False
    a3,C,12/9/2012,d,8,True,True,C,1,2,False
    a3,C,12/9/2012,d,8,True,True,D,1,2,True
    a3,C,12/9/2012,d,8,True,True,E,1,2,False
    

    【讨论】:

    • 非常感谢您解释这个概念和答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多