解析特定的XML到CSV格式
问题描述:
我如何使用一些的bash/shell脚本,改变这个输入解析特定的XML到CSV格式
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<runJobReturn xmlns="http://xml.org" xmlns:ns1="http://xml.org" xsi:type="ns1:runJobReturn">
<ns1:item xsi:type="ns1:ArrayOf_xsd_string">
<ns1:item xsi:type="xsd:string">15-02-2013</ns1:item>
<ns1:item xsi:type="xsd:string">Benjamin</ns1:item>
<ns1:item xsi:type="xsd:string">MASSY</ns1:item>
</ns1:item>
<ns1:item xsi:type="ns1:ArrayOf_xsd_string">
<ns1:item xsi:type="xsd:string">15-02-2013</ns1:item>
<ns1:item xsi:type="xsd:string">Ronald</ns1:item>
<ns1:item xsi:type="xsd:string">MASSY</ns1:item>
</ns1:item>
<ns1:item xsi:type="ns1:ArrayOf_xsd_string">
<ns1:item xsi:type="xsd:string">15-02-2013</ns1:item>
<ns1:item xsi:type="xsd:string">Zachary</ns1:item>
<ns1:item xsi:type="xsd:string">MASSY</ns1:item>
</ns1:item>
<ns1:item xsi:type="ns1:ArrayOf_xsd_string">
<ns1:item xsi:type="xsd:string">12</ns1:item>
<ns1:item xsi:type="xsd:string">13</ns1:item>
</ns1:item>
<ns1:item xsi:type="ns1:ArrayOf_xsd_string">
<ns1:item xsi:type="xsd:string">12</ns1:item>
<ns1:item xsi:type="xsd:string">13</ns1:item>
</ns1:item>
</runJobReturn>
</soapenv:Body>
的输出:
15-02-2013|Benjamin|MASSY
15-02-2013|Ronald|MASSY
15-02-2013|Zachary|MASSY
12|13
12|13
输入来自卷曲。我试过使用sed: echo $ INP | tr -d“\ n”| SED -e 'S/< [^>] *>/\ N/G' 但在输出保持值相乘
答
您真的不应该使用regex to parse XML。在bash中运行XSLT非常简单。
我建议运行从command line(XSLT 2.0)或运行XMLStarlet(XSLT 1.0)运行的Saxon-HE的Java版本。
实例:
XSLT 2.0(撒克逊)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="http://xml.org">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="ns1:runJobReturn/ns1:item">
<xsl:value-of select="ns1:item" separator="|"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
XSLT 1.0(XMLStarlet,撒克逊,Xalan的等)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="http://xml.org">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="ns1:runJobReturn/ns1:item">
<xsl:apply-templates select="ns1:item"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="ns1:item">
<xsl:if test="not(position()=1)">
<xsl:text>|</xsl:text>
</xsl:if>
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
任一这些样式表中的一个,应用于你的输入XML,将产生你想要的输出:
15-02-2013|Benjamin|MASSY
15-02-2013|Ronald|MASSY
15-02-2013|Zachary|MASSY
12|13
12|13
答
这里之间的新线是一种快速AWK一行程序:
echo $INP |awk -F '[<>]' '$2 ~ "xsd:string" {row = row "|" $3} $2 == "/ns1:item" {print substr(row, 2) ; row = ""}'
不要使用regex/sed/awk来处理xml。和[重复](http://stackoverflow.com/questions/13317053/how-should-i-go-about-converting-xml-into-csv) – BeniBela 2013-02-15 12:26:41