This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: 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@mulberrytech.com
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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]