tequila tequila - 2 years ago 60
HTML Question

How to create html table from XML element attributes and XML tags using xslt

I'm really new to xslt so I would be very thankful if someone can help me...
I have a XML like this:

<dummy>
<element name="O">
<description/>
</element>
<element name="L">
<description>abstract for L</description>
</element>
<element name="Sd">
<description>Description for Sd</description>
</element>
<element name="Dh">
<description/>
</element>
<element name="P">
<description/>
</element>
<element name="S">
<description>Some description for S</description>
</element>
<element name="A">
<description/>
</element>
<L>2010</L>
<A>58.78</A>
<O>O</O>
<Sd>1101</Sd>
<S>0.00</S>
<A>368.38</A>
<L>2009</L>
<Sd>1103</Sd>
</dummy>


I have to had a final html table like this ( using xslt "1.0"):

<tr>
<td>
I have to select only non element tags one by one, and then replace the tag with the
description of the same element name (in case that decription does not exists then display only element name).
</td>
<td>
Value of non element tag
</td>
</tr>


4 example ( upper xml)
[in something like for-each]: take <L> 2010 </L>


then search for element name = "L" ( if description exists = true take
description else "L") and
display abstract for L 2010

So the final output 4 given xml should be:

<tr><td> abstract for L </td> <td> 2010 </td> </tr>
<tr><td> A </td> <td> 58.78 </td> </tr>
<tr><td> O </td> <td> O </td> </tr>
<tr><td> Description for Sd </td> <td> 1101 </td> </tr>
<tr><td> Some description for S </td> <td> 0.00 </td> </tr>
<tr><td> A </td> <td> 368.38 </td> </tr>
<tr><td> abstract for L </td> <td> 2009</td> </tr>
<tr><td> Description for Sd </td> <td> 1103 </td> </tr>


The xslt must be written in xslt = "1.0"

Answer Source

I think you could make use of a key here, to look up your element nodes by the name attribute

<xsl:key name="elements" match="element" use="@name" />

Firstly, you would need to match all your non-element nodes, like so

<xsl:apply-templates select="dummy/*[not(self::element)]" />

Then to look up the description of the matching element you could then use the key set up earlier

<xsl:apply-templates select="key('elements', local-name())"/>

You would have two matching templates for the element nodes in this case; one for element nodes with a description, and one for those without.

Here is the full XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" indent="yes"/>
   <xsl:key name="elements" match="element" use="@name"/>

   <xsl:template match="/">
      <table>
         <xsl:apply-templates select="dummy/*[not(self::element)]"/>
      </table>
   </xsl:template>

   <xsl:template match="*[not(self::element)]">
      <tr>
         <td>
            <xsl:apply-templates select="key('elements', local-name())"/>
         </td>
         <td>
            <xsl:value-of select="."/>
         </td>
      </tr>
   </xsl:template>

   <xsl:template match="element">
      <xsl:value-of select="@name"/>
   </xsl:template>

   <xsl:template match="element[description[node()]]">
      <xsl:value-of select="description"/>
   </xsl:template>
</xsl:stylesheet>

When applied to your sample XML, the following HTML is output:

<table>
   <tr>
      <td>abstract for L</td>
      <td>2010</td>
   </tr>
   <tr>
      <td>A</td>
      <td>58.78</td>
   </tr>
   <tr>
      <td>O</td>
      <td>O</td>
   </tr>
   <tr>
      <td>Description for Sd</td>
      <td>1101</td>
   </tr>
   <tr>
      <td>Some description for S</td>
      <td>0.00</td>
   </tr>
   <tr>
      <td>A</td>
      <td>368.38</td>
   </tr>
   <tr>
      <td>abstract for L</td>
      <td>2009</td>
   </tr>
   <tr>
      <td>Description for Sd</td>
      <td>1103</td>
   </tr>
</table>
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download