I have a sample XML and I wanted to convert it to HTML Table but the table header should come from XML elements , example:
Have a look at attached xml and xsl, something I am missing (I am new to XML world , now to showcase some of data so I have to output data in XML, and XML looks better when styled and hence all this exercise)
<root>
<Device>
<Stat>
<Name>A</Name>
<Hardware>B</Hardware>
<Software>C</Software>
<Version>D</Version>
<State>E</State>
</Stat>
<Configuration>
<Up>
<Option1>2000</Option1>
<Option2>2500000</Option2>
<Option3>0</Option3>
<Option4>0</Option4>
<Option5>NA</Option5>
</Up>
<Down>
<Option1>2000</Option1>
<Option2>2500000</Option2>
<Option3>0</Option3>
<Option4>0</Option4>
<Option5>NA</Option5>
</Down>
</Configuration>
</Device>
<Device>
<Stat>
<Name>e</Name>
<Hardware>f</Hardware>
<Software>g</Software>
<Version>h</Version>
<State>i</State>
</Stat>
<Configuration>
<Up>
<Option1>2000</Option1>
<Option2>2500000</Option2>
<Option3>0</Option3>
<Option4>0</Option4>
<Option5>NA</Option5>
</Up>
<Down>
<Option1>2000</Option1>
<Option2>2500000</Option2>
<Option3>0</Option3>
<Option4>0</Option4>
<Option5>NA</Option5>
</Down>
</Configuration>
</Device>
</root>
XSLT
<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 border="1">
<xsl:call-template name="tablesetup" />
<xsl:apply-templates />
</table>
</xsl:template>
<xsl:template name ="tablesetup">
<tr>
<th colspan="{count(/root/Stat/*)}">
<xsl:if test="Configuration[*]">
<xsl:attribute name="rowspan">2</xsl:attribute>
</xsl:if>
<xsl:text>Stat</xsl:text>
</th>
<xsl:if test="/root/Configuration[*]">
<th colspan="{count(/root/Configuration/*/*)}">
<xsl:text>Configuration</xsl:text>
</th>
</xsl:if>
</tr>
<tr>
<xsl:for-each select="/root/Configuration/*">
<th colspan="{count(*)}">
<xsl:value-of select="local-name()" />
</th>
</xsl:for-each>
</tr>
<tr>
<xsl:apply-templates select="/root/Stat/*" mode="header" />
<xsl:apply-templates select="/root/Configuration/*/*" mode="header" />
</tr>
<tr>
<xsl:apply-templates select="/root/Stat/*" mode="row" />
<xsl:apply-templates select="/root/Configuration/*/*" mode="row" />
</tr>
</xsl:template>
<xsl:template match="*" mode="header">
<th>
<xsl:value-of select="local-name()" />
</th>
</xsl:template>
<xsl:template match="*" mode="row">
<td>
<xsl:value-of select="." />
</td>
</xsl:template>
</xsl:stylesheet>
Expected Output:
Header should look like this and then in next 2 rows table data should follow since we have 2 'Device' element
For you header cells, instead of doing as currently
You need to adjust this to only check the first Stat and Configuration cells
This assumes all the Stat and Configuration elements have the same structure. (Otherwise it become much harder)
For the rows, currently it does
Instead, replace it with a line to select individual Device elements, which correspond to your rows:
And then it is in the template that matches Device where you output the row data
Try this XSLT
When applied to your XML, the following is output