[
Lists Home |
Date Index |
Thread Index
]
| > I was wondering if there was a way of using XSLT to return a
| > distinct set of
| > values from an XML document?
| >
| > e.g.
| >
| > <TAG1>
| > <TAG2>John</TAG2>
| > <TAG2>Fred</TAG2>
| > <TAG2>John</TAG2>
| > </TAG>
Using the new features for Grouping from the XSLT 2.0 working draft
(together with the SAXON 7.0 processor [3] that lets you experiment
with them), you could take a document like:
<TAG1>
<TAG2>John</TAG2>
<TAG2>Fred</TAG2>
<TAG2>John</TAG2>
<TAG2>Fred</TAG2>
<TAG2>Abigail</TAG2>
<TAG2>John</TAG2>
<TAG2>Steve</TAG2>
</TAG1>
And produce an output like:
Distinct TAG2 values in alphabetical order are
1. Abigail (1)
2. Fred (2)
3. John (3)
4. Steve (1)
Using a stylesheet like in [1] below.
By slightly changing the stylesheet, you could
have the distinct elements listed by the number
of times they appear in the document, then by
alphabetical order using a stylesheet like in [2] below
to produce output like:
Distinct TAG2 values in order of most appearance are
1. John (3)
2. Fred (2)
3. Abigail (1)
4. Steve (1)
Here are the stylesheets:
=========== [1] ===========
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:text>Distinct TAG2 values in alphabetical order are
</xsl:text>
<!-- Works with Saxon 7.0 implementing XSLT 2.0 Draft -->
<xsl:for-each-group select="/TAG1/TAG2" group-by=".">
<xsl:sort select="."/>
<xsl:value-of select="position()"/>
<xsl:text>. </xsl:text>
<xsl:value-of select="current-group()[1]"/>
<xsl:text> (</xsl:text>
<xsl:value-of select="count(current-group())"/>
<xsl:text>)</xsl:text>
<xsl:if test="position() != last()"><xsl:text>
</xsl:text></xsl:if>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
=========== [2] ===========
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:text>Distinct TAG2 values in order of most appearance are
</xsl:text>
<!-- Works with Saxon 7.0 implementing XSLT 2.0 Draft -->
<xsl:for-each-group select="/TAG1/TAG2" group-by=".">
<xsl:sort data-type="number" select="count(current-group())" order="descending"/>
<xsl:sort select="."/>
<xsl:value-of select="position()"/>
<xsl:text>. </xsl:text>
<xsl:value-of select="current-group()[1]"/>
<xsl:text> (</xsl:text>
<xsl:value-of select="count(current-group())"/>
<xsl:text>)</xsl:text>
<xsl:if test="position() != last()"><xsl:text>
</xsl:text></xsl:if>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
=========== [3] ===========
SAXON 7.0 http://saxon.sourceforge.net/#F7.0
_____________________________________________________________________
Steve Muench - Developer, Product Manager, XML Evangelist, Author
"Simplifying J2EE and EJB Development with BC4J"
http://otn.oracle.com/products/jdev/htdocs/j2ee_with_bc4j/j2ee_with_bc4j.html
"Building Oracle XML Applications" - www.oreilly.com/catalog/orxmlapp
|