• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1238
  • Last Modified:

XML/XSL Multi Level Grouping examples wanted

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
silsuba
Asked:
silsuba
  • 3
  • 2
1 Solution
 
Vivek ThangaswamyCommented:
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
 
Geert BormansCommented:
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
 
silsubaAuthor Commented:
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
Geert BormansCommented:
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
 
Vivek ThangaswamyCommented:
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
 
Geert BormansCommented:
mmh, that is where I looked, did not find any munchian nested grouping in there
0

Featured Post

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!

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now