Direct and short solution :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/*"> <table><xsl:apply-templates select="row"/></table> </xsl:template> <xsl:template match="row[1]"> <tr><xsl:apply-templates select="*" mode="header"/></tr> <xsl:call-template name="standardRow"/> </xsl:template> <xsl:template match="row" name="standardRow"> <tr><xsl:apply-templates select="*"/></tr> </xsl:template> <xsl:template match="row/*"> <td><xsl:apply-templates select="node()"/></td> </xsl:template> <xsl:template match="row/*" mode="header"> <th><xsl:value-of select="name()"/></th> </xsl:template> </xsl:stylesheet>
when applied to the first XML document provided :
<rows> <row> <AccountId>BlPUAA0</AccountId> <AccountName>Initech</AccountName> <AcocuntStatus>Client</AcocuntStatus> </row> <row> <AccountId>CJxIAAW</AccountId> <AccountName>Intertrode</AccountName> <AcocuntStatus>Prospect</AcocuntStatus> </row> </rows>
the desired, correct result is output:
<table> <tr> <th>AccountId</th> <th>AccountName</th> <th>AcocuntStatus</th> </tr> <tr> <td>BlPUAA0</td> <td>Initech</td> <td>Client</td> </tr> <tr> <td>CJxIAAW</td> <td>Intertrode</td> <td>Prospect</td> </tr> </table>
when applied to the second XML document provided:
<rows> <row> <AccountId>BlPUAA0</AccountId> <AccountName>Initech</AccountName> </row> <row> <AccountId>CJxIAAW</AccountId> <AccountName>Intertrode</AccountName> </row> </rows>
again the desired, correct result is obtained:
<table> <tr> <th>AccountId</th> <th>AccountName</th> </tr> <tr> <td>BlPUAA0</td> <td>Initech</td> </tr> <tr> <td>CJxIAAW</td> <td>Intertrode</td> </tr> </table>
source share