Skip to content Skip to sidebar Skip to footer

HTML Table Header From XML Element

I have a sample XML and I wanted to convert it to HTML Table but the table header should come from XML elements , example: Have a look at attached xml and xsl, something I am miss

Solution 1:

For you header cells, instead of doing as currently

    <th colspan="{count(/root/Stat/*)}">
       <xsl:if test="Configuration[*]">
          <xsl:attribute name="rowspan">2</xsl:attribute>

       </xsl:if>
       <xsl:text>Stat</xsl:text>
    </th>

You need to adjust this to only check the first Stat and Configuration cells

    <th colspan="{count(/root/Device[1]/Stat/*)}">
       <xsl:if test="/root/Device[1]/Configuration[*]">
          <xsl:attribute name="rowspan">2</xsl:attribute>
       </xsl:if>
       <xsl:text>Stat</xsl:text>
    </th>

This assumes all the Stat and Configuration elements have the same structure. (Otherwise it become much harder)

For the rows, currently it does

 <tr>
     <xsl:apply-templates select="Stat/*" mode="row" />
     <xsl:apply-templates select="Configuration/*/*" mode="row" />
 </tr>

Instead, replace it with a line to select individual Device elements, which correspond to your rows:

<xsl:apply-templates select="Device" />

And then it is in the template that matches Device where you output the row data

<xsl:template match="Device">
     <tr>
         <xsl:apply-templates select="Stat/*" mode="row" />
         <xsl:apply-templates select="Configuration/*/*" mode="row" />
     </tr>
</xsl:template>

Try this XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="/">
            <table border="1">
                 <xsl:apply-templates name="root" />
       </table>
</xsl:template>

<xsl:template match="root">
     <tr>
        <th colspan="{count(Device[1]/Stat/*)}">
           <xsl:if test="Device[1]/Configuration[*]">
              <xsl:attribute name="rowspan">2</xsl:attribute>
           </xsl:if>
           <xsl:text>Stat</xsl:text>
        </th>
        <xsl:if test="Device[1]/Configuration[*]">
           <th colspan="{count(Device[1]/Configuration/*/*)}">
              <xsl:text>Configuration</xsl:text>
           </th>
        </xsl:if>
     </tr>
     <tr>
         <xsl:for-each select="Device[1]/Configuration/*">
            <th colspan="{count(*)}">
               <xsl:value-of select="local-name()" />
            </th>
         </xsl:for-each>
     </tr>
     <tr>
         <xsl:apply-templates select="Device[1]/Stat/*" mode="header" />
         <xsl:apply-templates select="Device[1]/Configuration/*/*" mode="header" />
     </tr>
     <xsl:apply-templates select="Device" />
</xsl:template>

<xsl:template match="*" mode="header">
  <th>
     <xsl:value-of select="local-name()" />
  </th>
</xsl:template>

<xsl:template match="Device">
     <tr>
         <xsl:apply-templates select="Stat/*" mode="row" />
         <xsl:apply-templates select="Configuration/*/*" mode="row" />
     </tr>
</xsl:template>

<xsl:template match="*" mode="row">
  <td>
     <xsl:value-of select="." />
  </td>
</xsl:template>
</xsl:stylesheet>

When applied to your XML, the following is output

<table border="1">
  <tr>
    <th colspan="5" rowspan="2">Stat</th>
    <th colspan="10">Configuration</th>
  </tr>
  <tr>
    <th colspan="5">Up</th>
    <th colspan="5">Down</th>
  </tr>
  <tr>
    <th>Name</th>
    <th>Hardware</th>
    <th>Software</th>
    <th>Version</th>
    <th>State</th>
    <th>Option1</th>
    <th>Option2</th>
    <th>Option3</th>
    <th>Option4</th>
    <th>Option5</th>
    <th>Option1</th>
    <th>Option2</th>
    <th>Option3</th>
    <th>Option4</th>
    <th>Option5</th>
  </tr>
  <tr>
    <td>A</td>
    <td>B</td>
    <td>C</td>
    <td>D</td>
    <td>E</td>
    <td>2000</td>
    <td>2500000</td>
    <td>0</td>
    <td>0</td>
    <td>NA</td>
    <td>2000</td>
    <td>2500000</td>
    <td>0</td>
    <td>0</td>
    <td>NA</td>
  </tr>
  <tr>
    <td>e</td>
    <td>f</td>
    <td>g</td>
    <td>h</td>
    <td>i</td>
    <td>2000</td>
    <td>2500000</td>
    <td>0</td>
    <td>0</td>
    <td>NA</td>
    <td>2000</td>
    <td>2500000</td>
    <td>0</td>
    <td>0</td>
    <td>NA</td>
  </tr>
</table>

Post a Comment for "HTML Table Header From XML Element"