|
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
|
|
|
February 7th, 2008, 06:28 AM
|
Registered User
|
|
Join Date: Jan 2008
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
first n elements with highest counts in a group
Hi All,
I did a transformation of a XML file.The description is given below-
input XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<School>
<student rec='1'>
<name>Robart J</name>
</student>
<student rec='2'>
<name>Alex M; Peter R; Robart J</name>
</student>
<student rec='3'>
<name>Alex M;Robart J; Dave T</name>
</student>
<student rec='4'>
<name>Alex M;Robart J; Peter R</name>
</student>
</School>
XSLT , I used-
<School>
<xsl:for-each-group select=" School/student group-by="name/tokenize(., ';\s*')">
<xsl:sort select="current-grouping-key()"/>
<name count="{count(current-group())}">
<xsl:value-of select="current-grouping-key()"/>
</name>
</xsl:for-each-group>
</School>
Output I got-
<School>
<name count='4'>Robart J</name>
<name count='3'>Alex M</name>
<name count='2'>Peter R</name>
<name count='1'>Dave T</name>
</School>
Now I want a little change in output format. Instead of writing all the name elements I want to write only two name elements having highest count value.Like-
<School>
<name count='4'>Robart J</name>
<name count='3'>Alex M</name>
</School>
When I tried with this XSLT code-
<School>
<xsl:for-each-group select=" School/student group-by="name/tokenize(., ';\s*')">
<xsl:sort data-type="number" select="count(current-group())" order="descending" />
<xsl:sort select="current-grouping-key()"/>
<xsl:for-each select="current-group()" >
<xsl:if test="position()=2">
<name count="{count(current-group())}">
<xsl:value-of select="current-grouping-key()"/>
</name>
</xsl:if>
</xsl:for-each>
</xsl:for-each-group>
</School>
I m getting output like-
<School>
<name count='4'>Robart J</name>
<name count='3'>Alex M</name>
<name count='2'>Peter R</name>
</School>
That is all the name elements having more than or equal to 2 count value. But I wanted only the first two name elements having highest counts.
Thanks for help.
|
February 7th, 2008, 11:23 AM
|
Registered User
|
|
Join Date: Jan 2008
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Michael suggested one modification in the code I was trying as below-
<School>
<xsl:for-each-group select=" School/student
group-by="name/tokenize(., ';\s*')">
<xsl:sort data-type="number" select="count(current-group())"
order="descending" />
<xsl:sort select="current-grouping-key()"/>
<xsl:if test="position() <= 2">
<name count="{count(current-group())}">
<xsl:value-of select="current-grouping-key()"/>
</name>
</xsl:if>
</xsl:for-each-group>
</School>
And it is working.
Thanks Michael.
|
February 7th, 2008, 11:25 AM
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
I think the following code produces the result you want:
Code:
<xsl:for-each-group select="School/student" group-by="name/tokenize(., ';\s*')">
<xsl:sort select="count(current-group())" order="descending"/>
<xsl:if test="position() = (1, 2)">
<name count="{count(current-group())}">
<xsl:value-of select="current-grouping-key()"/>
</name>
</xsl:if>
</xsl:for-each-group>
|
February 8th, 2008, 07:21 AM
|
Registered User
|
|
Join Date: Jan 2008
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Thanks Martin for your input.
I tried the code suggested by you and Michael, both are working fine with saxon processor but when i used it with Altova, I was getting very odd output. Might be this is a problem of Altova.
Regards,
Manish
|
February 8th, 2008, 10:15 AM
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
I have tried Altova's command line tool in the version "AltovaXML Version 2008 sp1" and the result I get with my stylesheet is the same as the result with Saxon 9.
|
February 8th, 2008, 11:11 AM
|
|
Friend of Wrox
|
|
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
|
|
The answer I would give (having had a little experience with Altova's XSLT processor) is definitely. I frequently got 'weird' results, especially when using xsl:for-each-group instructions.
/- Sam Judson : Wrox Technical Editor -/
|
February 8th, 2008, 09:16 PM
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 430
Thanks: 28
Thanked 5 Times in 5 Posts
|
|
I find that the Saxon processor is much better and faster. Saxon supports the collection() function which is extremely powerful, especially when using the for-each-group. I use XMLspy to edit, but SAXON to do my XSLT 2.0 productions. I wish Altova would just use the Saxon9api.
my 2 cents.
Bones
|
|
|