Solved

XML/XSL Multi Level Grouping examples wanted

Posted on 2007-11-13
6
1,218 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!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Trouble parsing soap xml result 3 57
Fixed div within Bootstrap carousel item 11 61
Element alignment and word wrapping 9 75
Fixing Non-Standard characters in text 8 111
Browsers only know CSS so your awesome SASS code needs to be translated into normal CSS. Here I'll try to explain what you should aim for in order to take full advantage of SASS.
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 arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

839 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