我正在尝试将以下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>
感谢您的帮助。
答案 0 :(得分:1)
使用XSLT可以轻松解决这个问题,而无需在工作流程中引入Python,但是,如果必须使用Python,lxml.etree
可以方便地引入一个新的类lxml.etree.XSLT
,您可以利用它来利用它。< / p>
假设您的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)
答案 1 :(得分:0)
sal.attrib
就像dict一样:
row = dict(sal.attrib)
salc.attrib
也像dict一样。为了“扁平化” - 或者更确切地说,加入 - 两个词组,你可以使用dict.update:
row.update(salc.attrib)
假设每个SalC
元素都有col7
,col8
,cal9
和col10
属性,您只需为每个{{row.update(salc.attrib)
调用salc
1 {} sal
:
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