1

How can I, using some bash/shell script, transform this input

<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>

To this output:

15-02-2013|Benjamin|MASSY
15-02-2013|Ronald|MASSY
15-02-2013|Zachary|MASSY
12|13
12|13

Input is from curl. I've tried to use sed : echo $INP | tr -d "\n" | sed -e 's/<[^>]*>/\n/g' but in output remains multiply new lines between values

xto
  • 406
  • 2
  • 8
  • 1
    Don't use regex/sed/awk for processing xml. And [duplicate](http://stackoverflow.com/questions/13317053/how-should-i-go-about-converting-xml-into-csv) – BeniBela Feb 15 '13 at 12:26

2 Answers2

3

You really shouldn't use regex to parse XML. It's just as easy to run XSLT in bash.

I would recommend running either running the Java version of Saxon-HE from the command line (XSLT 2.0) or running XMLStarlet (XSLT 1.0).

Examples:

XSLT 2.0 (Saxon)

<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, etc.)

<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>

Either one of these stylesheets, applied to your input XML, will produce the output you wanted:

15-02-2013|Benjamin|MASSY
15-02-2013|Ronald|MASSY
15-02-2013|Zachary|MASSY
12|13
12|13
Community
  • 1
  • 1
Daniel Haley
  • 51,389
  • 6
  • 69
  • 95
2

Here is a quick awk one-liner:

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