Xslt for creating a dynamic table with custom headers

I would like to convert an XML document using xslt with a set of row nodes and column nodes into an xhtml table.

Column nodes define data for the corresponding row attribute. For example, the first column of a node indicates that the attribute of the row ID of the node should be hidden (i.e. Do not show in the table). The Caption element of a node column determines what the text of the column heading should be.

I have seen solutions in which you know the attributes that you want to translate into columns ahead of time, but I'm not sure how to use the appropriate column data to format the headers.

Input:

<TableData> <Columns> <Column Name="ID" Hidden="true" /> <Column Name="Name" Caption="Item Name" /> <Column Name="Desc" Caption="Item Description" /> </Columns> <Rows> <Row ID="0" Name="A" /> <Row ID="1" Name="B" Desc="Some description"/> <Row ID="3" Name="C" /> </Rows> </TableData> 

The desired output would be a table in (x) html something like this:

 Item Name | Item Description -------------------------------------- A | B | Some Description C | 
+4
source share
1 answer

This conversion is :

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:key name="RowAttribsByName" match="Row/@*" use="concat(generate-id(..), '|', name())"/> <xsl:variable name="vColNames" select= "/*/Columns/*[not(@Hidden = 'true')]/@Name"/> <xsl:template match="/*"> <table border="1"> <tr> <xsl:apply-templates select="Columns/*"/> </tr> <xsl:apply-templates select="Rows/Row"/> </table> </xsl:template> <xsl:template match="Column[not(@Hidden = 'true')]"> <td><xsl:value-of select="@Caption"/></td> </xsl:template> <xsl:template match="Row"> <tr> <xsl:apply-templates select="$vColNames"> <xsl:with-param name="pRowId" select="generate-id()"/> </xsl:apply-templates> </tr> </xsl:template> <xsl:template match="Column/@*"> <xsl:param name="pRowId"/> <td width="50%"> <xsl:value-of select= "key('RowAttribsByName', concat($pRowId, '|', .) ) "/> </td> </xsl:template> </xsl:stylesheet> 

when applied to the provided XML document :

 <TableData> <Columns> <Column Name="ID" Hidden="true" /> <Column Name="Name" Caption="Item Name" /> <Column Name="Desc" Caption="Item Description" /> </Columns> <Rows> <Row ID="0" Name="A" /> <Row ID="1" Name="B" Desc="Some description"/> <Row ID="3" Name="C" /> </Rows> </TableData> 

creates the desired, correct result :

 <table border="1"> <tr> <td>Item Name</td> <td>Item Description</td> </tr> <tr> <td width="50%">A</td> <td width="50%"/> </tr> <tr> <td width="50%">B</td> <td width="50%">Some description</td> </tr> <tr> <td width="50%">C</td> <td width="50%"/> </tr> </table> 
+3
source

Source: https://habr.com/ru/post/1386226/


All Articles