XML for CSV using XSLT
XML IS:
<projects> <project> <name ID="A" StartDate='2012-01-01' EndDate='2012-01-30'>Shockwave</name> <language>Ruby</language> <Manager ID="M1">Nathan</Manager> </project> <project> <name ID="B" StartDate='2012-01-01' EndDate='2012-02-30'>Other</name> <language>Erlang</language> <Manager ID="M2">Kristi</Manager> </project> </projects> I want to copy this XML to CSV using XSLT. There are 1000 such projects. How can I get the result shown below in csv:
A;2012-01-01;2012-01-30;Shockwave;Ruby;M1;Nathan|B;2012-01-01;2012-02-30;Other;Erlang;M2;Kristi| Try something like that. It will display any attributes before the element text.
XML input
<projects> <project> <name ID="A">Shockwave</name> <language>Ruby</language> </project> <project> <name ID="B">Other</name> <language>Erlang</language> </project> </projects> XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="project"> <xsl:apply-templates select="@*|node()"/> <xsl:text>
</xsl:text> </xsl:template> <xsl:template match="@*"> <xsl:value-of select="."/> <xsl:if test="../text() or parent::project"> <xsl:text>,</xsl:text> </xsl:if> </xsl:template> <xsl:template match="*[ancestor::project]"> <xsl:apply-templates select="@*"/> <xsl:if test="preceding-sibling::*"> <xsl:text>,</xsl:text> </xsl:if> <xsl:value-of select="."/> </xsl:template> </xsl:stylesheet> Exit
A,Shockwave,Ruby B,Other,Erlang EDIT NEW REQUIREMENTS
XML input
<projects> <project> <name ID="A" StartDate='2012-01-01' EndDate='2012-01-30'>Shockwave</name> <language>Ruby</language> <Manager ID="M1">Nathan</Manager> </project> <project> <name ID="B" StartDate='2012-01-01' EndDate='2012-02-30'>Other</name> <language>Erlang</language> <Manager ID="M2">Kristi</Manager> </project> </projects> XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="project"> <xsl:apply-templates select="@*|node()"/> <xsl:text>|</xsl:text> </xsl:template> <xsl:template match="@*"> <xsl:if test="count(parent::*/@*)=1 and not(parent::project)"> <xsl:text>;</xsl:text> </xsl:if> <xsl:value-of select="."/> <xsl:if test="parent::project or (last())"> <xsl:text>;</xsl:text> </xsl:if> </xsl:template> <xsl:template match="*[ancestor::project]"> <xsl:apply-templates select="@*"/> <xsl:if test="preceding-sibling::* and not(@*)"> <xsl:text>;</xsl:text> </xsl:if> <xsl:value-of select="."/> </xsl:template> </xsl:stylesheet> Exit
A;2012-01-01;2012-01-30;Shockwave;Ruby;M1;Nathan|B;2012-01-01;2012-02-30;Other;Erlang;M2;Kristi| Use the solution you contacted, but change the line
<xsl:for-each select="child::*"> to
<xsl:for-each select="child::*|attribute::*"> This will result in a selection of attributes as well as nodes.