Extract list and count of different values

Here should go questions about transforming XML with XSLT and FOP.
ra0543
Posts: 80
Joined: Wed Jan 14, 2009 12:50 pm

Extract list and count of different values

Post by ra0543 »

I have data of the following form:

<a>
<b att="x"> ... </b>
<b att="c"> ... </b>
<b att="y"> ... </b>
<b att="z"> ... </b>
<b att="x"> ... </b>
<b att="x"> ... </b>
<b att="z"> ... </b>
<b att="c"> ... </b>
</a>

I want to generate a table based on this data in the following format, a list of all the values used for att paired with the number of b elements that have each att. The values for att are not restricted by the schema.

Code: Select all

att number of elements
c 2
x 3
y 1
z 2
I can see how to do this when I know what the possible values of att are using count(descendant:b[att='c']) and so on. But I don't know how to dynamically build a list of each of the different att values used. As usual, I'm sure this is easy to do and I'm just not seeing the obvious solution. Any help will be appreciated.
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Re: Extract list and count of different values

Post by george »

This is very easy with XSLT 2.0:

Code: Select all


<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="a">
<xsl:text>att&#9;&#9;number of elements&#10;</xsl:text>
<xsl:for-each-group select="b" group-by="@att">
<xsl:value-of select="current-grouping-key()"/>
<xsl:text>&#9;&#9;</xsl:text>
<xsl:value-of select="count(current-group())"/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
Best Regards,
George
George Cristian Bina
ra0543
Posts: 80
Joined: Wed Jan 14, 2009 12:50 pm

Re: Extract list and count of different values

Post by ra0543 »

Brilliant. Thanks.

Can I use for-each-group to produce groups of the actual elements with interspersed material like group headings? e.g.

<a>
<c>Type C</c>
<b att="c"> ... </b>
<b att="c"> ... </b>
<c>Type X</c>
<b att="x"> ... </b>
<b att="x"> ... </b>
<b att="x"> ... </b>
<c>Type Y</c>
<b att="y"> ... </b>
<c>Type Z</c>
<b att="z"> ... </b>
<b att="z"> ... </b>
</a>

where the <b> elements are also then sorted within their groups by their content.
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Re: Extract list and count of different values

Post by george »

Sure

Code: Select all


<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="a">
<a>
<xsl:for-each-group select="b" group-by="@att">
<c type="{current-grouping-key()}"/>
<xsl:for-each select="current-group()">
<xsl:sort select="."/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:for-each-group>
</a>
</xsl:template>
</xsl:stylesheet>
Best Regards,
George
George Cristian Bina
Post Reply