Using XSL Variable and Axes to format XML data into HTML having elements grouped by a tag

Following XSL converts the xml data into a format where first tag of the element is converted into heading and all elements having the same value for first tag will appear in a table below that heading. The Xml elements must be sorted by first tag.

To understand the transformation, consider the following Xml:

<mydata>
 <contact>
   <name>Mark</name>
   <telephone>34546343</telephone>
   <description>Work</description>
 </contact>
 <contact>
   <name>Mark</name>
   <telephone>98884748</telephone>
   <description>Home</description>
 </contact>=
 <contact>
   <name>Mark</name>
   <telephone>23456123</telephone>
   <description>Mobile</description>
 </contact>
 <contact>
   <name>William</name>
   <telephone>23098764</telephone>
   <description>Mobile</description>
 </contact>
 <contact>
   <name>William</name>
   <telephone>45645356</telephone>
   <description>Work</description>
 </contact>
</mydata>

The XSL generates the following output:

Contact: Mark

Telephone Description
34546343 Work
98884748 Home
23456123 Mobile

Contact: William

Telephone Description
23098764 Mobile
45645356 Work

XSL is following:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
 <xsl:template match="/">
 <html>
   <body>
     <xsl:for-each select="mydata/contact">
       <xsl:if test="name != preceding-sibling::contact&#91;1&#93;/name or position() = 1">

        <H3>
         Contact: <xsl:value-of select="name"/>
         </H3>

         <table border="1">
         <tr bgcolor="#9acd32">
           <th>Telephone</th>
           <th>Description</th>
         </tr>

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

        <xsl:variable name="curObject" select="name"/>
         <xsl:apply-templates select="following-sibling::contact&#91;name = $curObject&#93;"></xsl:apply-templates>


         </table>
       </xsl:if>
     </xsl:for-each>

  </body>
 </html>
 </xsl:template>

 <xsl:template match="contact">
   <tr>
     <td> <xsl:value-of select="telephone"/></td>
     <td> <xsl:value-of select="description"/></td>
   </tr>
 </xsl:template>
</xsl:stylesheet>

Leave a Reply

Your email address will not be published. Required fields are marked *