Solved

XML/XSL Multi Level Grouping examples wanted

Posted on 2007-11-13
6
1,215 Views
Last Modified: 2013-11-18
Hello Experts;

Trying to learn XML and working on creating a multi-level grouping.  I have read all I can find on the Muenchian Method and think I understand a single level grouping.  However I can't seem to grasp the multi-level grouping.

Does anyone know of examples available for viewing that would perhaps explain this.   I have read the Jenni Tennison articles but it's just not clicking.

Here is what I am trying to do

CATEGORY
     OWNER
          PROJECT
          PROJECT
     OWNER
          PROJECT

CATEGORY
      OWNER
          PROJECT
      OWNER
          PROJECT


Here is my XML:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="projects_2.xslt"?>
<projects>
  <project>
    <category>healthcare</category>
    <name>Medical Building Expansion</name>
    <owner>Christiana Care Health System </owner>
    <descp></descp>
    <iscomplete></iscomplete>
    <completiondate></completiondate>
  </project>
  <project>
    <category>healthcare</category>
    <name>Cancer Care Center</name>
    <owner>Christiana Care Health System </owner>
    <descp></descp>
    <iscomplete></iscomplete>
    <completiondate></completiondate>
  </project>
  <project>
    <category>healthcare</category>
    <name>Emergency Room Expansion and Renovation</name>
    <owner>Atlantic General Hospital</owner>
    <descp></descp>
    <iscomplete></iscomplete>
    <completiondate></completiondate>
  </project>
  <project>
    <category>senior care</category>
    <name>Methodist Country House Hall One Conversion</name>
    <owner>Peninsula United Methodist Homes, inc.</owner>
    <descp></descp>
    <iscomplete></iscomplete>
    <completiondate></completiondate>
  </project>
  <project>
    <category>senior care</category>
    <name>Cokesbury Village Christiana Court East</name>
    <owner>Peninsula United Methodist Homes, inc.</owner>
    <descp></descp>
    <iscomplete></iscomplete>
    <completiondate></completiondate>
  </project>


Here is my current XSL which gives me a single level sort:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="categories" match="project" use="category" />
<xsl:template match="/">
  <xsl:apply-templates />
</xsl:template>
  <xsl:template match="projects">
    <xsl:for-each select="//project[generate-id(.)=generate-id(key('categories',category))]">
      <xsl:sort select="name" order="ascending" />
      <h3>
        <xsl:value-of select="category"/>
      </h3>
      <table border="1">
        <tr>
          <th>Owner</th>
          <th>Project</th>
        </tr>
        <xsl:for-each select="key('categories',category)">
          <xsl:sort select="owner" />
          <tr>
            <td>
              <xsl:value-of select="owner" />
            </td>
            <td>
              <xsl:value-of select="name" />
            </td>
            <td>
            </td>
          </tr>
        </xsl:for-each>
      </table>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


Thanks for any advice or examples!


0
Comment
Question by:silsuba
  • 3
  • 2
6 Comments
 
LVL 11

Expert Comment

by:Vivek Thangaswamy
ID: 20278174
Hi,

You get the same in the following blog
http://vivekthangaswamy.blogspot.com/2006/09/xml-and-xslt-transformation-using-cnet.html
download the source code frm the blog
http://vivekthangaswamy.googlepages.com/Tools.zip

this .zip file conatins the sample for multi level grouping in XSLT
0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 20278452
just add another key
and make sure that you add an extra restriction in the muenchian method

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="categories" match="project" use="category" />
    <xsl:key name="owner" match="project" use="owner" />
    <xsl:output indent="yes"/>
    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>
    <xsl:template match="projects">
        <xsl:for-each select="project[generate-id(.)=generate-id(key('categories',category))]">
            <xsl:sort select="name" order="ascending" />
            <h3>
                <xsl:value-of select="category"/>
            </h3>
            <table border="1">
                <tr>
                    <th>Owner</th>
                    <th>Project</th>
                    <th></th>
                </tr>
                    <xsl:variable name="thisCat" select="category"/>
                    <xsl:for-each select="../project[generate-id() = generate-id(key('owner', owner)[category = $thisCat][1])]">
                        <xsl:sort select="owner" />
                        <xsl:for-each select="key('owner', owner)[category = $thisCat]">
                            <tr>
                                <xsl:if test="position() = 1">
                                    <td rowspan="{count(key('owner', owner)[category = $thisCat])}">
                                        <xsl:value-of select="owner" />
                                    </td>
                                </xsl:if>
                                 <td>
                                    <xsl:value-of select="name" />
                                </td>
                                <td>
                                </td>
                            </tr>
                        </xsl:for-each>
                    </xsl:for-each>
             </table>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>


I added this key
    <xsl:key name="owner" match="project" use="owner" />

and added a restriction on category in the muenchian
                   <xsl:variable name="thisCat" select="category"/>
                    <xsl:for-each select="../project[generate-id() = generate-id(key('owner', owner)[category = $thisCat][1])]">

You could work with a concatenated key as a second key,
which would be faster if this is a huge dataset
but get started first with this simple straightforward solution

cheers

Geert

0
 

Author Comment

by:silsuba
ID: 20285025
Gertone;  Thanks works like a charm (but you knew that already, didnt ya?) This helps me learn how it's done.

I would assume that one would just repeat this process if one would want further grouping?  Any limits to the levels of grouping permitted?
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
LVL 60

Expert Comment

by:Geert Bormans
ID: 20287475
Welcome,

well, I tested before posting
I don't think there is a limit to nesting,
I have a 6 level deep nested grouping on a 20 MByte file runing smooth reports without any problems
The complexity will be the maintenance of the 6 deep nested for-eaches, so the code becomes complex

If you run into performance issues, and your architecture allows it,
you could migrate to XSLT2, there is a concept of for-each-group which is very handy

@vivekthangaswamy,
I posted after you had started an answer because I failed to find an example of nested muenchian in your reference
Can you point out the nesting example please, I am always interested to see and understand alternative solutions

cheers

Geert
0
 
LVL 11

Expert Comment

by:Vivek Thangaswamy
ID: 20287634
When you extract tools.zip you will get the tools folder, inside that Sample Data and TestViewer two folders available. Inside Sample data folder you can see moviecontainer.xslt file it contains the example.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 20287646
mmh, that is where I looked, did not find any munchian nested grouping in there
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Microsoft Edge 9 99
use of cookies and regulations 1 86
Extract XML Data from using TSQL 5 53
JavaScript and Regular Expressions - How to implement date validation? 7 58
Preface In the first article: A Better Website Login System (http://www.experts-exchange.com/A_2902.html) I introduced the EE Collaborative Login System and its intended purpose. In this article I will discuss some of the design consideratio…
Browsing the questions asked to the Experts of this forum, you will be amazed to see how many times people are headaching about monster regular expressions (regex) to select that specific part of some HTML or XML file they want to extract. The examp…
The viewer will the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)

785 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question