2013-01-15 71 views
1

我正在嘗試將以下XML數據壓扁爲CSV類型的表數據。Python解析嵌套的XML並壓扁數據

我可以獲取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> 

謝謝您的幫助。

+0

做你試過beautifullsoup? – Somesh

回答

0

sal.attrib是類似字典的:

row = dict(sal.attrib) 

salc.attrib也是類似字典的。 「平坦」 - 或者更確切地說,加入 - 這兩個類型的字典togther,你可以使用dict.update

row.update(salc.attrib) 

假設每個SalC元素有col7col8cal9col10屬性,你可以叫row.update(salc.attrib)每個salcsal


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 
+0

非常感謝你解釋這個概念,也是答案。 – user1978967

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) 
+0

非常感謝。 – user1978967