xml - XSL: how to improve this code? -
sorry, i'm learning xsl , display table this:
| param1 | param2 | -------+------+--------- | p1.1 | p1.2 | p2 | -------+------+--------- | a11 | a21 | b01 | | a12 | a22 | b02 |
now, have xml:
<?xml version="1.0" encoding="utf-8"?> <tb> <col title="param1"> <row name="1"> <stats name="p1.1" >a11</stats> <stats name="p1.2" >a12</stats> </row> <row name="2"> <stats name="p1.1" >a21</stats> <stats name="p1.2" >a22</stats> </row> </col> <col title="param2"> <row name="1"> <stats name="p2" >b01</stats> </row> <row name="2"> <stats name="p2" >b02</stats> </row> </col>
and xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:for-each select="tb"> <table class="data_table" style="width: 100%; background:gray"> <thead> <tr> <xsl:for-each select="col"> <xsl:choose> <xsl:when test="count(row[1]/stats) > 1"> <th colspan="{count(row[1]/stats)}"> <xsl:value-of select="@title" /> </th> </xsl:when> <xsl:otherwise> <th><xsl:value-of select="@title" /></th> </xsl:otherwise> </xsl:choose> </xsl:for-each> </tr> <tr> <xsl:for-each select="col/row[1]/stats"> <th><xsl:value-of select="@name" /></th> </xsl:for-each> </tr> </thead> <tbody> <tr> <xsl:for-each select="col/row[1]/stats"> <td> <xsl:value-of select="." /> </td> </xsl:for-each> </tr> <tr> <xsl:for-each select="col/row[2]/stats"> <td> <xsl:value-of select="." /> </td> </xsl:for-each> </tr> </tbody> </table> </xsl:for-each>
it's works how improve code using single assemble table rows? in example have 2 rows (a11|a21|b01 , a12|a22|b02) , 3 columns may change (20 rows, 4 columns...). maybe need group cells belonging same row.
the first thing improve xslt use templates. once that's done, can following able handle arbitrary number of rows.
this solution assumes every <col>
in source data have <row>
every row need:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:template match="/tb"> <table class="data_table" style="width: 100%; background:gray"> <thead> <tr> <xsl:apply-templates select="col" mode="titles" /> </tr> <tr> <xsl:apply-templates select="col/row[1]/stats" mode="titles" /> </tr> </thead> <tbody> <xsl:apply-templates select="col[1]/row" /> </tbody> </table> </xsl:template> <xsl:template match="col" mode="titles"> <th> <xsl:apply-templates select="(.)[row[1]/stats[2]]" mode="colspan" /> <xsl:value-of select="@title"/> </th> </xsl:template> <xsl:template match="col" mode="colspan"> <xsl:attribute name="colspan"> <xsl:value-of select="count(row[1]/stats)"/> </xsl:attribute> </xsl:template> <xsl:template match="stats" mode="titles"> <th> <xsl:value-of select="@name" /> </th> </xsl:template> <xsl:template match="row"> <tr> <xsl:apply-templates select="../../col/row[@name = current()/@name]/stats" /> </tr> </xsl:template> <xsl:template match="stats"> <td> <xsl:value-of select="." /> </td> </xsl:template> </xsl:stylesheet>
when run on sample input, result is:
<table class="data_table" style="width: 100%; background:gray"> <thead> <tr> <th colspan="2">param1</th> <th>param2</th> </tr> <tr> <th>p1.1</th> <th>p1.2</th> <th>p2</th> </tr> </thead> <tbody> <tr> <td>a11</td> <td>a12</td> <td>b01</td> </tr> <tr> <td>a21</td> <td>a22</td> <td>b02</td> </tr> </tbody> </table>
Comments
Post a Comment