xsl automatic tables
This is an open discussion with 5 replies, filed under XSLT.
Search
My approach:
<xsl:key name="col-by-Name" match="Column" use="@Name" /> <xsl:key name="tab-by-Name" match="Table" use="@Name" /> <xsl:template match="/data/friends"> <ul> <!-- distinct table names --> <xsl:for-each select=" Table[ count( . | key('tab-by-Name', @Name)[1] ) = 1 ] "> <li> <xsl:value-of select="@Name"/> <xsl:value-of select="' - '"/> <!-- simple: the item count is the node count of the key --> <xsl:value-of select=" count( key('tab-by-Name', @Name) ) "/> <xsl:variable name="current" select="@Name" /> <ul> <xsl:value-of select="' '"/> <xsl:variable name="endheader" select="false" /> <xsl:for-each select="../Table [@Name = $current]/*"> <xsl:if test="position() = 1 and @Name = 'ID'"><ul></xsl:if> <xsl:if test="position() > 1 and @Name = 'ID'"></ul><ul></xsl:if> <li><xsl:value-of select="@Name" /> : <xsl:value-of select="." /></li> <xsl:if test="position()=last()"></ul></xsl:if> </xsl:for-each> </ul> </li> </xsl:for-each> </ul> </xsl:template>
But this is only an apporach as it is far from a table.
If sb could help me, how to get
- the headings (@Name)
- the table data (values)
Thanks for your help in advance.
The last - how can i put in above xsl in the xsl-if:
'<ul>' instead of <ul>
?
@tirili - Try this. I’m using the Muenchian Method for grouping.
Here’s your XML…
<?xml version="1.0" encoding="UTF-8"?> <friends> <table name="Me"> <column name="ID">1</column> <column name="Name">Doe</column> <column name="FName">John</column> </table> <table name="Friends"> <column name="ID">1</column> <column name="Name">Doe</column> <column name="FName">Jane</column> <column name="Email">jane at doe.com</column> </table> <table name="Friends"> <column name="ID">2</column> <column name="Name">Doe</column> <column name="FName">Mike</column> <column name="Email">mike at doe.com</column> </table> </friends>
Here’s the XSLT
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <xsl:key name="table-rows" match="table" use="@name"/> <xsl:template match="/"> <xsl:apply-templates select="friends/table[count(.|key('table-rows',@name)[1])=1]" mode="group"></xsl:apply-templates> </xsl:template> <xsl:template match="table" mode="group"> <h2> <xsl:value-of select="@name"/> </h2> <table> <tr> <th>ID</th> <th>Name</th> <th>Fname</th> <th>Email</th> </tr> <xsl:apply-templates select="key('table-rows',@name)" mode="item"/> </table> </xsl:template> <xsl:template match="table" mode="item"> <tr> <xsl:apply-templates select="column"/> </tr> </xsl:template> <xsl:template match="column"> <td><xsl:value-of select="."/></td> </xsl:template> </xsl:stylesheet>
Here’s the output…
<h2>Me</h2> <table> <tr> <th>ID</th> <th>Name</th> <th>Fname</th> <th>Email</th> </tr> <tr> <td>1</td> <td>Doe</td> <td>John</td> </tr> </table> <h2>Friends</h2> <table> <tr> <th>ID</th> <th>Name</th> <th>Fname</th> <th>Email</th> </tr> <tr> <td>1</td> <td>Doe</td> <td>Jane</td> <td>jane at doe.com</td> </tr> <tr> <td>2</td> <td>Doe</td> <td>Mike</td> <td>mike at doe.com</td> </tr> </table>
Thanks for the hint. But how can I produce the headings automatically from the @name attribute? What if I have different counts of “column”? As you see, in first we do not have the column “email”.
Got it! Sorry about that. Try this…
XML
<?xml version="1.0" encoding="UTF-8"?> <friends> <table name="Me"> <column name="ID">1</column> <column name="Name">Doe</column> <column name="FName">John</column> </table> <table name="Friends"> <column name="ID">1</column> <column name="Name">Doe</column> <column name="FName">Jane</column> <column name="Email">jane at doe.com</column> </table> <table name="Friends"> <column name="ID">2</column> <column name="Name">Doe</column> <column name="FName">Mike</column> <column name="Email">mike at doe.com</column> </table> </friends>
XSLT
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <xsl:key name="table-rows" match="table" use="@name"/> <xsl:template match="/"> <xsl:apply-templates select="friends/table[count(.|key('table-rows',@name)[1])=1]" mode="group"/> </xsl:template> <xsl:template match="table" mode="group"> <xsl:param name="table-name" select="@name"/> <h2> <xsl:value-of select="@name"/> </h2> <table> <tr> <xsl:apply-templates select="column[../@name=$table-name]" mode="row-header-item"></xsl:apply-templates> </tr> <xsl:apply-templates select="key('table-rows',@name)" mode="item"/> </table> </xsl:template> <xsl:template match="table" mode="item"> <tr> <xsl:apply-templates select="column" mode="detail"/> </tr> </xsl:template> <xsl:template match="column" mode="row-header-item"> <th><xsl:value-of select="@name"/></th> </xsl:template> <xsl:template match="column" mode="detail"> <td><xsl:value-of select="."/></td> </xsl:template> </xsl:stylesheet>
Output
<h2>Me</h2> <table> <tr> <th>ID</th> <th>Name</th> <th>FName</th> </tr> <tr> <td>1</td> <td>Doe</td> <td>John</td> </tr> </table> <h2>Friends</h2> <table> <tr> <th>ID</th> <th>Name</th> <th>FName</th> <th>Email</th> </tr> <tr> <td>1</td> <td>Doe</td> <td>Jane</td> <td>jane at doe.com</td> </tr> <tr> <td>2</td> <td>Doe</td> <td>Mike</td> <td>mike at doe.com</td> </tr> </table>
Perfect! Thank you.
Thomas.
Create an account or sign in to comment.
Hi all,
I have following XML, and I need to display a table with the contents. I hope sb can help me.
The result should look like this