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 June 30th, 2008, 12:34 PM
Registered User
 
Join Date: Jun 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default Muenchian Grouping on individual nodes in xslt1.0

Hi,


  I am trying to do grouping on nodesets. Below given is my input xml (This is a sample i took from my original problem in order to make the problem simpler)

<?xml version="1.0" encoding="UTF-8"?>
 <Root>
   <Level>
      <Level1>
         <Field11>sdfds</Field11>
         <Field12>dfdf</Field12>
      </Level1>
      <Level2>
         <Field21>sdfds</Field21>
         <Field22>dfdf</Field22>
      </Level2>
      <Level1>
         <Field11>sdfds</Field11>
         <Field12>dfdf</Field12>
      </Level1>
   </Level>
   <Level>
      <Level1>
         <Field11>sdfds</Field11>
         <Field12>dfdf</Field12>
      </Level1>
      <Level2>
         <Field21>sdfds</Field21>
         <Field22>dfdf</Field22>
      </Level2>
      <Level3>
         <Field31>sdfds</Field31>
         <Field32>dfdf</Field32>
      </Level3>
      <Level2>
         <Field21>sdfds</Field21>
         <Field22>dfdf</Field22>
      </Level2>
   </Level>
 </Root>

I would like to get the output as in the following order (for my complete solution this order is very important)

   <Level1>
      <Field11>sdfds</Field11>
      <Field12>dfdf</Field12>
   </Level1>
   <Level1>
      <Field11>sdfds</Field11>
      <Field12>dfdf</Field12>
   </Level1>
   <Level2>
      <Field21>sdfds</Field21>
      <Field22>dfdf</Field22>
   </Level2>
   <Level1>
      <Field11>sdfds</Field11>
      <Field12>dfdf</Field12>
   </Level1>
   <Level2>
      <Field21>sdfds</Field21>
      <Field22>dfdf</Field22>
   </Level2>
   <Level2>
      <Field21>sdfds</Field21>
      <Field22>dfdf</Field22>
   </Level2>
   <Level3>
      <Field31>sdfds</Field31>
      <Field32>dfdf</Field32>
   </Level3>



 I have used Muenchian Grouping to group it and i am getting

   <Level1>
      <Field11>sdfds</Field11>
      <Field12>dfdf</Field12>
   </Level1>
   <Level1>
      <Field11>sdfds</Field11>
      <Field12>dfdf</Field12>
   </Level1>
   <Level1>
      <Field11>sdfds</Field11>
      <Field12>dfdf</Field12>
   </Level1>
   <Level2>
      <Field21>sdfds</Field21>
      <Field22>dfdf</Field22>
   </Level2>
   <Level2>
      <Field21>sdfds</Field21>
      <Field22>dfdf</Field22>
   </Level2>
   <Level2>
      <Field21>sdfds</Field21>
      <Field22>dfdf</Field22>
   </Level2>
   <Level3>
      <Field31>sdfds</Field31>
      <Field32>dfdf</Field32>
   </Level3>

and this is my stylesheet

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" />

    <xsl:key name="levels" match="Level/*" use="local-name ()" />

    <xsl:template match="/">



        <xsl:for-each select="//Level/*[generate-id() = generate-id(key('levels', local-name())[1])]">

                <xsl:sort select="local-name ()" />

                    <xsl:variable name="localN" select="local-name ()" />
                    <xsl:for-each select="key ('levels', $localN )">
                        <xsl:copy-of select="." />
                    </xsl:for-each>
        </xsl:for-each>

    </xsl:template>

</xsl:stylesheet>

I understand the output is because the key is applied to the document instead of each individual level element. Is there a way by which i can apply the key to each individual level element?

Thanks,
sudhish


 
Old June 30th, 2008, 01:33 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Since the order of the output is very important, it's important that we can tell which output element results from which input. In your example there are three Level1 elements, which appear at positions 1, 3, and 4 in the input, but at positions 1, 2 and 4 in the output. Since they all have identical content it's very hard to see what the correspondence is.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old June 30th, 2008, 02:09 PM
Registered User
 
Join Date: Jun 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi Michael,

 Thanks for responding. I actually would like to group elements inside each parent level element. But in my output i don't really require the level element (It can appear though). So the order is as it appears in the parent level element.

The desired output with level element (level element is not really required, thats why i omitted that code from my xsl)

  <Level>
   <Level1>
      <Field11>sdfds</Field11>
      <Field12>dfdf</Field12>
   </Level1>
   <Level1>
      <Field11>sdfds</Field11>
      <Field12>dfdf</Field12>
   </Level1>
   <Level2>
      <Field21>sdfds</Field21>
      <Field22>dfdf</Field22>
   </Level2>
</Level>
<Level>
   <Level1>
      <Field11>sdfds</Field11>
      <Field12>dfdf</Field12>
   </Level1>
   <Level2>
      <Field21>sdfds</Field21>
      <Field22>dfdf</Field22>
   </Level2>
   <Level2>
      <Field21>sdfds</Field21>
      <Field22>dfdf</Field22>
   </Level2>
   <Level3>
      <Field31>sdfds</Field31>
      <Field32>dfdf</Field32>
   </Level3>
</Level>

I am looking for a way to group elements inside each Level element.


Thanks,
Sudhish

 
Old July 1st, 2008, 01:20 AM
Authorized User
 
Join Date: May 2008
Posts: 32
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="Root">
        <root>
            <xsl:apply-templates select="Level"/>
        </root>
    </xsl:template>
    <xsl:template match="Level">
        <xsl:apply-templates select="node()" mode="levels">
            <xsl:sort select="name()"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="node()" mode="levels">
        <xsl:copy-of select="."/>
    </xsl:template>
</xsl:stylesheet>
 
Old July 1st, 2008, 03:38 AM
Registered User
 
Join Date: Jun 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

 Thank You Volder.

 I apologize for not giving a clear problem statement. I wanted to simplify the question for better clarity. So i tried to focus my question on the point where i am struck. By doing so, i forgot to mention an important aspect of the problem.

  Actually Grouping is important here as i have to do some operations like count (this is only one case) on these element groups (for example, level1 element group in first level element).

 I tried concatenating generate-id of parent Level element with the local-name of child Level* element in xsl:key use, but its not working.

Thanks,
Sudhish

 
Old July 1st, 2008, 06:21 AM
Authorized User
 
Join Date: May 2008
Posts: 32
Thanks: 0
Thanked 0 Times in 0 Posts
Default

what do you mean by "grouping" here? your elements are already grouped initially inside every separate element 'Level'.

I thought you were talking about proper ordering inside every Level, but now it seems for me that you were asking about smth diffirent.

So it is better if you clearly describe what you need, based on your first input sample, and we could help you.

 
Old July 1st, 2008, 07:02 AM
Registered User
 
Join Date: Jun 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Volder,

 I mean, Grouping similar elements inside each level element and do some operations on those elements.

For example,

   <Level>
      <Level1>
         <Field11>sdfds</Field11>
         <Field12>dfdf</Field12>
      </Level1>
      <Level2>
         <Field21>sdfds</Field21>
         <Field22>dfdf</Field22>
      </Level2>
      <Level1>
         <Field11>sdfds</Field11>
         <Field12>dfdf</Field12>
      </Level1>
   </Level>

 In the above xml has a level element containing level1, level2 and level1 child elements. I would like to group these elemenets and peform operations on level1 group and level2 group (if any).

Similary my next level element in the xml contains level1, level2, level3 and level2 elements. I would like group these elements and perform operations on level1 group, level2 group and level3 group.

Hope this makes everything clear... I apologize for not making myself clear on the previous posts..

Thanks,
Sudhish

 
Old July 1st, 2008, 08:41 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

I think the stylesheet posted earlier that sorts the Level/* elements does what you want.
If you really want to apply Muenchian grouping with a key that concatenates the generated id of the parent element with the name then here is a sample stylesheet:
Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes"/>

  <xsl:key name="by-level"
           match="Level/*"
           use="concat(generate-id(..), '_', local-name())"/>

  <xsl:template match="Root">
    <xsl:copy>
      <xsl:apply-templates select="Level"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Level">
    <xsl:apply-templates select="*[generate-id() = generate-id(key('by-level', concat(generate-id(..), '_', local-name()))[1])]">
      <xsl:sort select="local-name()" data-type="text"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="Level/*">
    <xsl:copy-of select="key('by-level', concat(generate-id(..), '_', local-name()))"/>
  </xsl:template>

</xsl:stylesheet>
As far as I can tell it gives the described output with your XML sample input.

--
  Martin Honnen
  Microsoft MVP - XML
 
Old July 1st, 2008, 09:53 AM
Authorized User
 
Join Date: May 2008
Posts: 32
Thanks: 0
Thanked 0 Times in 0 Posts
Default

[quot]Hope this makes everything clear...[/quot]
sorry, buddy, but it is still unclear for me and it would be nice - if you give an expected output for the input in your last reply.

 
Old July 1st, 2008, 10:32 AM
Registered User
 
Join Date: Jun 2008
Posts: 7
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Martin Thanks for your post. Thats exactly what i was looking for..






Similar Threads
Thread Thread Starter Forum Replies Last Post
grouping problem at xslt1.0 joshuaa XSLT 4 July 15th, 2008 08:08 AM
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
NESTED GROUPING USING XSLT1.0 jhansib4u Classic ASP XML 0 November 19th, 2007 09:12 AM
Muenchian Grouping Chamkaur XSLT 1 June 21st, 2006 10:51 AM





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