【问题标题】:Parse specific XML to CSV format将特定的 XML 解析为 CSV 格式
【发布时间】:2013-02-15 21:10:14
【问题描述】:

我怎样才能使用一些 bash/shell 脚本来转换这个输入

<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

输入来自 curl。我试过使用 sed : 回声 $INP | tr -d "\n" | sed -e 's/]*>/\n/g' 但在输出中仍然在值之间乘以新行

【问题讨论】:

  • 不要使用 regex/sed/awk 来处理 xml。还有duplicate

标签: xml bash


【解决方案1】:

你真的不应该使用regex to parse XML。在 bash 中运行 XSLT 一样容易。

我建议从command line (XSLT 2.0) 运行Saxon-HE 的Java 版本或运行XMLStarlet (XSLT 1.0)。

例子:

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、Saxon、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 = ""}'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 2015-06-20
      相关资源
      最近更新 更多