Bryant Bryant - 3 months ago 8
HTML Question

How to transform XML attributes to an HTML table

Here is an excerpt from an xsl document (inside a template technically):

<table>
<tr>
<th>INSTANCE</th>
<th>SWVER</th>
<th>SYSTEMID</th>
<th>SYSTIME</th>
<th>SYSMEM</th>
<th>CUTMEM</th>
<th>FILEMEM</th>
<th>CALCONFIG</th>
</tr>
<tr>
<td><xsl:value-of select='@INSTANCE'/></td>
<td><xsl:value-of select='@SWVER'/></td>
<td><xsl:value-of select='@SYSTEMID'/></td>
<td><xsl:value-of select='@SYSTIME'/></td>
<td><xsl:value-of select='@SYSMEM'/></td>
<td><xsl:value-of select='@CUTMEM'/></td>
<td><xsl:value-of select='@FILEMEM'/></td>
<td><xsl:value-of select="@CALCONFIG"/></td>
</tr>
</table>


Is there some way that I can avoid the redundancy of writing out the attributes both as table headers and as the attribute selection? I cannot use external sources.

I was thinking I could define some xsl variable that contains a basic structure, as follows and generate the table from there.

<list>
<item>INSTANCE</item>
...
<item>CALCONFIG</item>
</list>


The XML data is just a bunch of tags, of the same value that contain at least the above listed attributes. Each tag looks something like this:

<THING INSTANCE="boop" SWVER="foo" SYSTEMID="123"
...
CALCONFIG="cal.cfg" SOMETHINGELSE="bar"
/>

Answer

To illustrate the point I made in a comment to your question, consider the following example:

XML

<root>
    <item color="red" name="alpha" size="small" garbage="123" id="1"/>
    <item color="green" name="bravo" size="medium" garbage="456" id="2"/>
    <item color="blue" name="charlie" size="large" garbage="789" id="3"/>
</root>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://www.example.com/my"
exclude-result-prefixes="my">
<xsl:output method="html" encoding="utf-8"/>
<xsl:strip-space elements="*"/>

<my:columns>
    <col>id</col>
    <col>name</col>
    <col>size</col>
    <col>color</col>
</my:columns>
<xsl:variable name="columns" select="document('')/xsl:stylesheet/my:columns" />

<xsl:template match="/root">
    <table border="1">
        <tr>
            <xsl:for-each select="$columns/col">
                <th>
                    <xsl:value-of select="." />
                </th>
            </xsl:for-each>
        </tr>
        <xsl:for-each select="item">
            <xsl:variable name="attributes" select="@*" />
            <tr>
                <xsl:for-each select="$columns/col">
                    <td>
                        <xsl:value-of select="$attributes[name()=current()]" />
                    </td>
                </xsl:for-each>
            </tr>
        </xsl:for-each> 
    </table>
</xsl:template>

</xsl:stylesheet>

Result (rendered)

enter image description here