1

I Have a XML file like this

<Tester author="Name" id="16384543">
  <insert tableName="sampletable">
    <column name="id" valueNumeric="2"/>
    <column name="name" value="kathy"/>
    <column name="active" valueBoolean="true"/>
    <column name="age" valueNumeric="2"/>
  </insert>
  <insert tableName="sampletable">
    <column name="id" valueNumeric="23"/>
    <column name="name" value="Queen"/>
    <column name="active" valueBoolean="true"/>
    <column name="age" valueNumeric="29"/>
  </insert>
  <insert tableName="sampletable">
    <column name="id" valueNumeric="25"/>
    <column name="name" value="varshan"/>
    <column name="active" valueBoolean="false"/>
    <column name="age" valueNumeric="5"/>
  </insert>
</Tester>

I need to convert the XML into CSV like below:

id,name,active,age
2,kathy,TRUE,2
23,Queen,TRUE,29
25,varshan,FALSE,5

Requriement:

These column attributes will be dynamic and it will be different for different XMLs. Can someone help?

1 Answer 1

1

Here's a way this could be done.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    version="1.0">

  <xsl:output method="text"/>

  <xsl:template match="/">
    <!-- Header -->
    <xsl:apply-templates select="Tester/insert[1]">
      <xsl:with-param name="header">true</xsl:with-param>
    </xsl:apply-templates>
    <!-- Data -->
    <xsl:apply-templates select="Tester/insert"/>
  </xsl:template>
  
  <xsl:template match="insert">
    <xsl:param name="header"/>
    <xsl:for-each select="column">
      <!-- For the header take the name attribute, else take the attribute starting with value -->
      <xsl:choose>
        <xsl:when test="$header='true'">
          <xsl:value-of select="@name"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="@*[starts-with(name(),'value')]"/>
        </xsl:otherwise>
      </xsl:choose>
      <!-- Insert comma between values, except for last value insert new line -->
      <xsl:choose>
        <xsl:when test="position()=last()">
          <xsl:text>&#xa;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>,</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:template>
  
</xsl:stylesheet>

See it working here: https://xsltfiddle.liberty-development.net/3MXNWN6

Sign up to request clarification or add additional context in comments.

11 Comments

Thanks Sebastien for help! I missed adding header and it is <?xml version="1.1" encoding="UTF-8" standalone="no"?> and it says Error parsing XML input at 1:16 : Version number '1.1' is invalid. Line 1, position 16..... Any thought on this?
I don't know why you have XML version="1.1" and if your document is declared as standalone="no" then it must be dependent on some other document? As you can see from the URL I posted the code I posted works, it's hard to know why it doesn't work on your input without seeing it. Try modifying the header of your file to version="1.0".
XMl file is one which was generated by liquibase and its version is 1.1..so wont be able to change the version number .. But wondering why XSL is not able to parse this XML version!!!
Which XSLT engine are you using?
I am using Eclipse Version: Neon.3 Release (4.6.3) for this.. Did i answered ur question?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.