此外,考慮XSLT,特殊用途的轉換語言,可以直接將XML轉換爲CSV甚至從解析其他XML文件使用其document()
函數。 Python的lxml模塊可以處理XSLT 1.0腳本。確保所有三個xmls都駐留在同一個目錄中。
XSLT腳本(保存爲文件名爲.xsl --a特別.XML file--要在Python下面的稱呼)
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output version="1.0" encoding="UTF-8" method="text" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/projects">
<xsl:copy>
<xsl:text>Pid,Clientid,ClientName,ClientActive,ProjectName,ProjectActive,Billable,BillBy,HourlyRate,</xsl:text>
<xsl:text>Budget,OverbudgetNotificationPercentage,CreatedAt,UpdatedAt,StartsOn,EndsOn,Estimate,EstimateBy,</xsl:text>
<xsl:text>Notes,CostBudget,TeammemberName1,CostRate1,TeammemberName2,CostRate2,TeammemberName3,CostRate3,</xsl:text>
<xsl:text>TaskId1,TotalHours1,TaskId2,TotalHours2
</xsl:text>
<xsl:apply-templates select="project"/>
</xsl:copy>
</xsl:template>
<xsl:template match="project">
<xsl:variable name="clientid" select="client-id"/>
<xsl:value-of select="concat(id, ',')"/>
<xsl:variable name="delimiter"><xsl:text>","</xsl:text></xsl:variable>
<xsl:for-each select="document('clients.xml')/clients/client[id=$clientid]/*
[local-name()='id' or local-name()='name' or local-name()='active']">
<xsl:value-of select="." />
<xsl:if test="position() != last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:value-of select="concat(',',name,',',active,',',billable,',',bill-by,',',hourly-rate,',',budget,',',
over-budget-notification-percentage,',',created-at,',',updated-at,',',starts-on,',',ends-on,',',
estimate,',',estimate-by,',',notes,',',cost-budget,',')"/>
<xsl:for-each select="document('teammembers.xml')/root/team_members/item[cid=$clientid]/*
[local-name()='full_name' or local-name()='cost_rate']">
<xsl:if test="position() < 5">
<xsl:value-of select="." />
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="document('ClientItems_teammembers.xml')/root/tasks/item[cid=$clientid]/*
[local-name()='task_id' or local-name()='total_hours']">
<xsl:if test="position() < 5">
<xsl:value-of select="." />
<xsl:if test="position() != last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:transform>
的Python腳本(轉化projects.xml和讀取在XSLT另外兩個)
import lxml.etree as ET
def transformXML():
dom = ET.parse('projects.xml')
xslt = ET.parse('XSLTscript.xsl')
transform = ET.XSLT(xslt)
newdom = transform(dom)
with open('Output.csv'),'w') as f:
f.write(str(newdom))
if __name__ == "__main__":
transformXML()
輸出
Pid,Clientid,ClientName,ClientActive,ProjectName,ProjectActive,Billable,
BillBy,HourlyRate,Budget,OverbudgetNotificationPercentage,CreatedAt,
UpdatedAt,StartsOn,EndsOn,Estimate,EstimateBy,Notes,CostBudget,TeammemberName
1,CostRate1,TeammemberName2,CostRate2,TeammemberName3,CostRate3,
TaskId1,TotalHours1,TaskId2,TotalHours2
11493770,4708336,AFB,true,Services - Consulting - AH,true,true,Project,
421.28,16.0,80.0,2016-08-16T03:22:51Z,
2016-08-16T03:22:51Z,,,16.0,project,Random
notes,,BobR,76.0,BobR,76.0,BobR,76.0,6357137,0.0,6357138,0.0,
你可以發佈更完整的輸入XML(帶根標籤),而不是片段的[重複的例子(http://stackoverflow.com/help/mcve)?希望的csv輸出結果可能會有幫助,並說明您的文字說明。 – Parfait
請閱讀[MCVE] – boardrider
@Pfafait好的。我會盡量簡化它,並用更簡化的工作示例更新問題。真實的數據,我不能張貼。所以我需要修改它,一些xml文件非常大。第一個的根標籤簡單地是 ,第二個是 ,然後它只是我用不同ID和字段內容放在那裏的幾百個。我爲這個病毒拉取實時數據,需要製作一個示例文件,在這裏發佈一個使用它們的工作腳本。它現在只需要一個xml就可以工作。但我不知道如何結合 –