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

Popular posts from this blog

javascript - Laravel datatable invalid JSON response -

java - Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; -

sql server 2008 - My Sql Code Get An Error Of Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value '8:45 AM' to data type int -