?
Solved

XML/XSL Multi Level Grouping examples wanted

Posted on 2007-11-13
6
Medium Priority
?
1,233 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 2000 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Don't Cry: How Liquid Web is Ensuring Security

WannaCry is just the start. Read how Liquid Web is protecting itself and its customers against new threats.

Question has a verified solution.

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

Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
JavaScript has plenty of pieces of code people often just copy/paste from somewhere but never quite fully understand. Self-Executing functions are just one good example that I'll try to demystify here.
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Suggested Courses

770 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