Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old May 1st, 2008, 04:32 AM
Registered User
 
Join Date: Aug 2007
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Default help with Muenchian method grouping and html table

 Here's my input xml...

<ugcourses>
   <course>
      <code>055</code>
      <name>B.Ed. (Music Education)</name>
      <year>1</year>
   </course>
   <course>
      <code>055</code>
      <name>B.Ed. (Music Education)</name>
      <year>2</year>
   </course>
   <course>
      <code>055</code>
      <name>B.Ed. (Music Education)</name>
      <year>3</year>
   </course>
   <course>
      <code>055</code>
      <name>B.Ed. (Music Education)</name>
      <year>4</year>
   </course>
   <course>
      <code>443</code>
      <name>Acting Studies</name>
      <year>2</year>
   </course>
   <course>
      <code>443</code>
      <name>Acting Studies</name>
      <year>3</year>
   </course>
   <course>
      <code>448</code>
      <name>Bachelor in Midwifery Studies</name>
      <year>4</year>
   </course>
   <course>
      <code>446</code>
      <name>Bachelor in Science (Nursing)</name>
      <year>1</year>
   </course>
   <course>
      <code>446</code>
      <name>Bachelor in Science (Nursing)</name>
      <year>2</year>
   </course>
   <course>
      <code>446</code>
      <name>Bachelor in Science (Nursing)</name>
      <year>3</year>
   </course>
   <course>
      <code>425</code>
      <name>B.Sc (Information Systems) Hons</name>
      <year>5</year>
  </course>
    <course>
      <code>459</code>
      <name>Bachelor in Dental Technology</name>
      <year>1</year>
   </course>
   <course>
      <code>459</code>
      <name>Bachelor in Dental Technology</name>
      <year>2</year>
   </course>
   <course>
      <code>459</code>
      <name>Bachelor in Dental Technology</name>
      <year>3</year>
   </course>
      <course>
      <code>458</code>
      <name>Bachelor in Science in Midwifery</name>
      <year>2</year>
   </course>
   <course>
      <code>023</code>
      <name>Biblical and Theological Studies</name>
      <year>2</year>
   </course>
   <course>
      <code>023</code>
      <name>Biblical and Theological Studies</name>
      <year>3</year>
   </course>
   <course>
      <code>023</code>
      <name>Biblical and Theological Studies</name>
      <year>4</year>
   </course>
</ugcourses>


Here's my desired output at a html table, with the year and course code displayed under correct heading
<table>
<tr><th>Course Name</td> <th>YR1 </th> <th>YR2 </th> <th>YR3 </th> <th>YR4 </th> <th>YR5 </th></tr>
<tr><td>Acting Studies</td> <td>.....</td> <td>2-443</td> <td>3-443</td> <td> </td> <td> </td></tr>
<tr><td>B.Ed. (Music Education)</td> <td>1-055</td> <td>2-055</td> <td>3-055</td> <td>4-055</td> <td> </td></tr>
<tr><td>Bachelor in Midwifery Studies</td> <td> </td> <td> </td> <td> </td> <td>4-448</td> <td> </td></tr>
<tr><td>Bachelor in Science (Nursing)</td> <td>1-446</td> <td>2-446</td> <td>3-446</td> <td> </td> <td> </td></tr>
<tr><td>B.Sc (Information Systems) Hons</td> <td> </td> <td> </td> <td> </td> <td> </td> <td>5-425</td></tr>
<tr><td>Bachelor in Dental Technology</td> <td>1-459</td> <td>2-459</td> <td>3-459</td> <td> </td> <td> </td></tr>
<tr><td>Bachelor in Science in Midwifery</td> <td> </td> <td>2-458</td> <td> </td> <td> </td> <td> </td></tr>
<tr><td>Biblical and Theological Studies</td> <td> </td> <td>2-023</td> <td>3-023</td> <td>4-023</td> <td> </td></tr>
<table>

And here's my attempt thus far...
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<xsl:key name="course-codes" match="course" use="code" />
<xsl:key name="courses-by-CODE" match="course" use="code" />
<xsl:key name="courses-by-year" match="course" use="year" />
<xsl:variable name="course-codes" select="/ugcourses/course[generate-id() = generate-id(key('course-codes', code)[1])]/code" />

<xsl:template match="/ugcourses">
<table width="100%" border="0" cellpadding="1" cellspacing="1">
  <tr>
    <th bgcolor="#eeeeee"><div align="left">Course Name</div></th>
    <th bgcolor="#eeeeee"><div align="center">First Year</div></th>
    <th bgcolor="#eeeeee"><div align="center">Second Year</div></th>
    <th bgcolor="#eeeeee"><div align="center">Third Year</div></th>
    <th bgcolor="#eeeeee"><div align="center">Fourth Year</div></th>
    <th bgcolor="#eeeeee"><div align="center">Fifth Year</div></th>
  </tr>
  <xsl:for-each select="$course-codes">
    <xsl:variable name="courses" select="key('courses-by-CODE', .)" />

    <tr>
    <td bgcolor="#cdd8fe"><xsl:value-of select="../name" /></td>
       <xsl:for-each select="$course-codes">
           <td bgcolor="#cdd8fe"><xsl:value-of select="$courses[code = current()]" /></td>
      </xsl:for-each>
    </tr>
  </xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>


Unfortunately, as this is my first attempt with the Meunchian method, It's not working quite right for me.

Any ideas?

Thanks!!
 
Old May 1st, 2008, 05:59 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Here is an XSLT 1.0 stylesheet that uses Muenchian grouping to group by course code:
Code:
<?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="course-by-code" match="course" use="code"/>

  <xsl:template match="/">
    <html lang="en">
      <head>
        <title>Course List</title>
      </head>
      <body>
        <xsl:apply-templates select="ugcourses"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="ugcourses">
    <table width="100%" border="0" cellpadding="1" cellspacing="1">
      <thead>
        <tr>
          <th bgcolor="#eeeeee">
            <div align="left">Course Name</div>
          </th>
          <th bgcolor="#eeeeee">
            <div align="center">First Year</div>
          </th>
          <th bgcolor="#eeeeee">
            <div align="center">Second Year</div>
          </th>
          <th bgcolor="#eeeeee">
            <div align="center">Third Year</div>
          </th>
          <th bgcolor="#eeeeee">
            <div align="center">Fourth Year</div>
          </th>
          <th bgcolor="#eeeeee">
            <div align="center">Fifth Year</div>
          </th>
        </tr>
      </thead>
      <tbody>
        <xsl:apply-templates select="course[generate-id() = generate-id(key('course-by-code', code)[1])]"/>
      </tbody>
    </table>
  </xsl:template>

  <xsl:template match="course">
    <tr>
      <td>
        <xsl:value-of select="name"/>
      </td>
      <xsl:variable name="years" select="key('course-by-code', code)"/>
      <xsl:for-each select="../course[position() &lt; 6]">
        <td>
          <xsl:choose>
            <xsl:when test="position() = $years/year">
              <xsl:value-of select="concat(position(), '-', $years/code)"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>#160;</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </td>
      </xsl:for-each>
    </tr>
  </xsl:template>
</xsl:stylesheet>
With XSLT 2.0 I would have used an xsl:for-each select="1 to 5" to produce the year output, with XSLT 1.0 you have to "cheat" and simply iterate over a node-set of nodes where you know you have at least five, in this case to course elements.

--
  Martin Honnen
  Microsoft MVP - XML
 
Old May 1st, 2008, 06:18 AM
Registered User
 
Join Date: Aug 2007
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Dear Martin, Your are a "star", Thank you very much

 
Old May 1st, 2008, 06:24 AM
samjudson's Avatar
Friend of Wrox
 
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
Default

A couple of points that will hopefully help in the future:

<xsl:key name="course-codes" match="course" use="code" />
<xsl:key name="courses-by-CODE" match="course" use="code" />

The above two keys are identical, so one is unneeded.

Code:
<xsl:for-each select="$course-codes">
    <xsl:variable name="courses" select="key('courses-by-CODE', .)" />

    <tr>
    <td bgcolor="#cdd8fe"><xsl:value-of select="../name" /></td>
       <xsl:for-each select="$course-codes">
The above code loops through $course-codes twice, so this is obviously not going to produce the produce the correct output. I think the second loop should have been "$courses".

However you then have the problem that each course is printed out with no regard for the year. As the number of years appears to be fixed at 5 I simply replaced the <xsl:for-each> with 5 <xsl:value-of> lines as below:

Code:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<xsl:key name="course-codes" match="course" use="code" />
<xsl:variable name="course-codes" select="/ugcourses/course[generate-id() = generate-id(key('course-codes', code)[1])]/code" />

<xsl:template match="/ugcourses">
<table width="100%" border="0" cellpadding="1" cellspacing="1">
 <tr>
   <th bgcolor="#eeeeee"><div align="left">Course Name</div></th>
   <th bgcolor="#eeeeee"><div align="center">First Year</div></th>
   <th bgcolor="#eeeeee"><div align="center">Second Year</div></th>
   <th bgcolor="#eeeeee"><div align="center">Third Year</div></th>
   <th bgcolor="#eeeeee"><div align="center">Fourth Year</div></th>
   <th bgcolor="#eeeeee"><div align="center">Fifth Year</div></th>
 </tr>
 <xsl:for-each select="$course-codes">
   <xsl:variable name="courses" select="key('course-codes', .)" />
   <tr>
     <td bgcolor="#cdd8fe"><xsl:value-of select="../name" /></td>
     <td bgcolor="#cdd8fe"><xsl:value-of select="$courses[year = 1]" /></td>
     <td bgcolor="#cdd8fe"><xsl:value-of select="$courses[year = 2]" /></td>
     <td bgcolor="#cdd8fe"><xsl:value-of select="$courses[year = 3]" /></td>
     <td bgcolor="#cdd8fe"><xsl:value-of select="$courses[year = 4]" /></td>
     <td bgcolor="#cdd8fe"><xsl:value-of select="$courses[year = 5]" /></td>
   </tr>
 </xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
/- Sam Judson : Wrox Technical Editor -/





Similar Threads
Thread Thread Starter Forum Replies Last Post
help with Muenchian method grouping... agentdz015 XSLT 1 April 7th, 2008 04:53 PM
Muenchian grouping amhicraig XSLT 1 December 5th, 2007 06:43 PM
Muenchian Grouping Chamkaur XSLT 1 June 21st, 2006 10:51 AM
Advanced Grouping Using the Muenchian Method Bodiam XSLT 0 August 8th, 2005 11:33 AM
Grouping XML by Muenchian Method - Urgent :-( xrow XSLT 5 September 28th, 2004 04:07 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.