RE: [xsl] Is it possible to group by name() ?

Subject: RE: [xsl] Is it possible to group by name() ?
From: "Casadome, Francisco" <Francisco.Casadome@xxxxxxxxxxxxxx>
Date: Wed, 18 Sep 2002 16:56:13 +0200
Thanks a lot Wendell !
I still have to practice qith this Muenchian method a little bit :^)

Frank.
-----Original Message-----
From: Wendell Piez [mailto:wapiez@xxxxxxxxxxxxxxxx] 
Sent: Wednesday, September 18, 2002 1:06 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] Is it possible to group by name() ?


Frank,

At 04:54 PM 9/17/2002, you wrote:
>I would appreciate some help on this. I have an XML that looks like 
>this:
>
><n0>
>         <n1>
>                 <a>text</a>
>                 <b>text</b>
>                 <c>text</c>
>         </n1>
>         <n1>
>                 <a>text</a>
>                 <c>text</c>
>         </n1>
>         <n1>
>                 <a>text</a>
>                 <b>text</b>
>                 <d>text</d>
>         </n1>
></n0>
>
>And what I would like to have is a list of the different nodes inside 
>n1 nodes. In the example above, the result should be: a,b,c,d.
>
>Is it possible to do something like this ?
><xsl:key name="groupbyname" match="/n0/n1/*" use="name()"/>
>
>And then use the muenchian method ? But how ?

You're right on track.

When using the Muenchian method, remember it works by doing two things. 
First, grouping, which you have down (your key does this). Then, 
de-duplicating by picking one node from each group -- using it to fire off 
processing the whole group if necessary (in your case it's not). Once 
you've mastered the two steps, it's only a matter of deciding how you want 
to traverse your nodes to get to them.

So you could do:

<xsl:for-each select="/n0/n1/*">
   <!-- iterates over all the candidate nodes -->
   <xsl:if test="count(.|key('groupbyname', name())[1]) = 1">
     <!-- throws away all but the first of each group -->
     <xsl:value-of select="name()"/>
     <!-- outputs the name you want -->
   </xsl:if>
</xsl:for-each>

Similarly, an entire stylesheet could look like:

<xsl:stylesheet version="1.0"
                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:output method="text"/>

<xsl:strip-space elements="*"/>
<!-- cleans things up a bit -->

<xsl:key name="groupbyname" match="/n0/n1/*" use="name()"/>

<xsl:template match="/n0/n1/*[count(.|key('groupbyname', name())[1]) = 1]">
   <!-- puts the selection logic into a template match -->
   <xsl:value-of select="concat(name(), '&#xA;')"/>
   <!-- inserting an extra line break for clarity --> </xsl:template>

<xsl:template match="text()">
   <!-- suppress text nodes as uninteresting --> </xsl:template>

</xsl:stylesheet>

Fun, huh?

Cheers,
Wendell


======================================================================
Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
   Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread