Re: [xsl] [Fwd: Muenchian method -- how to optimize this code ?]

Subject: Re: [xsl] [Fwd: Muenchian method -- how to optimize this code ?]
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Fri, 18 Aug 2006 15:23:25 +0530
On 8/18/06, Michael Fourneau <Michael.Fourneau@xxxxxxx> wrote:
=== Question 2 ===

    *  From this XML document, I'd like to created a table which contains:
          o in the first column: the titles found in the document ;
          o in the second column: the name of the members with such title ;
          o in the third column: all the customers which have this
            member - with this title - in their team.
    * How could I achieve this based on the Muenchian method ?

The result table should look like:

T1 NAME1 CUSTOMER1

NAME2 CUSTOMER2

T2 NAME1 CUSTOMER1

    T3   NAME2   CUSTOMER1
                 CUSTOMER2

T4 NAME3 CUSTOMER2

I am attempting to solve this part (would leave rest of your questions to others).

Given this XML:

<customers>
 <customer>
   <name>CUSTOMER1</name>
   <team>
     <member>
       <name>NAME1</name>
       <title>T1</title>
       <title>T2</title>
     </member>
     <member>
       <name>NAME2</name>
       <title>T3</title>
     </member>
   </team>
 </customer>
 <customer>
   <name>CUSTOMER2</name>
   <team>
     <member>
       <name>NAME3</name>
       <title>T4</title>
     </member>
     <member>
       <name>NAME2</name>
       <title>T3</title>
       <title>T1</title>
     </member>
   </team>
 </customer>
</customers>

This stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
	
<xsl:output method="html" indent="yes" />

<xsl:key name="by-title" match="title" use="." />

<xsl:template match="/">
 <html>
   <head>
     <title/>
   </head>
   <body>
     <table border="1">
       <tr>
          <th>Title</th>
          <th>Team member</th>
          <th>Customers</th>
       </tr>
       <xsl:for-each select="//title[generate-id() =
generate-id(key('by-title', .)[1])]">
          <xsl:variable name="title" select="." />
          <xsl:for-each select="//member[title = $title]">
            <xsl:choose>
	<xsl:when test="position() = 1">
	   <tr>
	      <td><xsl:value-of select="$title" /></td>
	      <td><xsl:value-of select="name" /></td>
	      <td><xsl:value-of select="../../name" /></td>
	   </tr>
	</xsl:when>
	<xsl:otherwise>
	   <tr>
	     <td></td>
	     <td>
	        <xsl:if test="not(preceding::member[title = $title]/name =
current()/name)">
	           <xsl:value-of select="name" />
	       </xsl:if>
	     </td>
	     <td><xsl:value-of select="../../name" /></td>
	   </tr>
	 </xsl:otherwise>
             </xsl:choose>
          </xsl:for-each>
       </xsl:for-each>
     </table>
   </body>
 </html>
</xsl:template>

</xsl:stylesheet>

Produces output:

<html>
  <head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     <title></title>
  </head>
  <body>
     <table border="1">
        <tr>
           <th>Title</th>
           <th>Team member</th>
           <th>Customers</th>
        </tr>
        <tr>
           <td>T1</td>
           <td>NAME1</td>
           <td>CUSTOMER1</td>
        </tr>
        <tr>
           <td></td>
           <td>NAME2</td>
           <td>CUSTOMER2</td>
        </tr>
        <tr>
           <td>T2</td>
           <td>NAME1</td>
           <td>CUSTOMER1</td>
        </tr>
        <tr>
           <td>T3</td>
           <td>NAME2</td>
           <td>CUSTOMER1</td>
        </tr>
        <tr>
           <td></td>
           <td></td>
           <td>CUSTOMER2</td>
        </tr>
        <tr>
           <td>T4</td>
           <td>NAME3</td>
           <td>CUSTOMER2</td>
        </tr>
     </table>
  </body>
</html>

I believe, this is what you want.

The solution is probably not very optimized.

--
Regards,
Mukul Gandhi

http://gandhimukul.tripod.com

Current Thread