I'm trying to convert an XML file into a nice-looking HTML table using XSL, and I can't for the life of me figure out how to get the columns all lined up properly. I found a similar question (Convert XML List to HTML Table Using XSL), which was informative (I'm pretty new to XSL in general so every little bit helps), but my XML is structured a bit more... irregularly:
<?xml version="1.0"?>
<root>
<Group>
<Type>Type1</Type>
<Desc>Desc1</Desc>
<Name>Name1</Name>
</Group>
<Group>
<Type>Type2</Type>
<Name>Name2</Name>
<State>State2</State>
</Group>
<Group>
<Type>Type3</Type>
<State>State3</State>
<Country>Country4</Country>
</Group>
</root>
Is there a good way to turn this into a well-formatted table? I'd prefer if it worked on the XML as it is like this, as if we ever add a new field to one of the Group elements, I don't want them to have to add the same tag to every other element (though if there's alternately a good way to automatically add all the missing children to a Group element that are present in other Group elements, that would be good too, maybe using a second XSLT that can run first). There's no backing schema for this XML, but one could be made if it helps.
Sorry if this has been answered before, I couldn't find anything closer besides the mentioned question and nothing about how to add the missing children to an element.
Here is my attempt at an XSLT 2.0 solution:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" version="5.0" encoding="UTF-8" indent="yes" />
<xsl:variable name="col-names" select="distinct-values(root/Group/*/node-name(.))"/>
<xsl:template match="root">
<table>
<thead>
<tr>
<xsl:for-each select="$col-names">
<th>
<xsl:value-of select="."/>
</th>
</xsl:for-each>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="Group"/>
</tbody>
</table>
</xsl:template>
<xsl:template match="Group">
<tr>
<xsl:variable name="this" select="."/>
<xsl:for-each select="$col-names">
<td>
<xsl:value-of select="$this/*[node-name(.) eq current()]"/>
</td>
</xsl:for-each>
</tr>
</xsl:template>
</xsl:transform>