2013-02-15 98 views
1

我如何使用一些的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' 但在輸出保持值相乘

+1

不要使用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

回答

3

您真的不應該使用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>&#xA;</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>&#xA;</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 
2

這裏之間的新線是一種快速AWK一行程序:

echo $INP |awk -F '[<>]' '$2 ~ "xsd:string" {row = row "|" $3} $2 == "/ns1:item" {print substr(row, 2) ; row = ""}'