Subject: Re: [xsl] grouping/position problem From: "M. David Peterson" <m.david.x2x2x@xxxxxxxxx> Date: Fri, 22 Apr 2005 08:11:01 -0600 |
Bruce (and group), I am still trying to find a stopping point but before it got too late I thought it best to showcase a quick sample of how you would go about solving this problem using the sample XML you provided. I will convert this into the proper namespaces and elements and check it in as soon as I can finish up this other item. The XML I used was: <?xml version="1.0" encoding="UTF-8"?> <list> <item author="five" year="2001"/> <item author="three" year="2003"/> <item author="four" year="2002"/> <item author="two" year="1998"/> <item author="one" year="2005"/> <item author="two" year="2000"/> <item author="four" year="1999"/> </list> Which I then processed with the following XSLT 2.0-based stylesheet: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <author> <xsl:apply-templates select="list"/> </author> </xsl:template> <xsl:template match="list"> <xsl:for-each-group select="item" group-by="@author"> <author-group author="{@author}"> <xsl:apply-templates select="current-group()"> <xsl:sort select="@author"/> <xsl:sort select="@year"/> </xsl:apply-templates> </author-group> </xsl:for-each-group> </xsl:template> <xsl:template match="item"> <item> <xsl:choose> <xsl:when test="position() = 1"> <xsl:apply-templates select="@author"/> <xsl:apply-templates select="@year" mode="standard-year-output"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="@year" mode="shorten-year-output"/> </xsl:otherwise> </xsl:choose> </item> </xsl:template> <xsl:template match="@author"> <xsl:attribute name="year"> <xsl:value-of select="."/> </xsl:attribute> </xsl:template> <xsl:template match="@year" mode="standard-year-output"> <xsl:attribute name="year"> <xsl:value-of select="."/> </xsl:attribute> </xsl:template> <xsl:template match="@year" mode="shorten-year-output"> <xsl:attribute name="year"> <xsl:value-of select="substring(., 3)"/> </xsl:attribute> </xsl:template> </xsl:stylesheet> When processed the following is the result output: <?xml version="1.0" encoding="UTF-8"?> <author> <author-group author="five"> <item year="2001"/> </author-group> <author-group author="three"> <item year="2003"/> </author-group> <author-group author="four"> <item year="1999"/> <item year="02"/> </author-group> <author-group author="two"> <item year="1998"/> <item year="00"/> </author-group> <author-group author="one"> <item year="2005"/> </author-group> </author> A couple things to note: - The output could have just as easily have been text. But to showcase where each author group starts and stops as well as the years contained within each group I felt this would be easier to understand for someone looking at this without any backround. - If XML was the format I would need this to be in at this stage of the transformation I would have probably held of from stripping the date to its 2 digit shorthand... of course now that I said that I realized I should have processed the date output using one of the many great additions to the 2.0 spec, date processing :) This will still work fine of course and if I had more time I would change it right now but for now I think its safe to leave it as is :) - actually there was one other point but for the life of me I cant remember what it was. If it comes to me and it seems important enough to post I will do just that. As I mentioned earlier I am finishing a few things on some other projects but as soon as I am done with the new and improved version of the projects stylesheet for this item I will check it in and ping you to let you know. If you need this before late afternoon you may want to try to use the above as a guide to recreate the logic for that stylesheet and if you get into a jam, ping me and I will see if I can rearrange things a bit. If any of the rest of you have comments, questions or concerns please, by all mean :D On 4/22/05, Bruce D'Arcus <bdarcus@xxxxxxxxx> wrote: > I'm having some problems with grouping and position(). > > For illustration, you could imagine an input source like: > > <list> > <item author="five" year="2001"/> > <item author="three" year="2003"/> > <item author="four" year="2002"/> > <item author="two" year="1998"/> > <item author="one" year="2005"/> > <item author="two" year="2000"/> > <item author="four" year="1999"/> > </list> > > I need to group and sort by author, then by year, and then pass some > parameters that are based on the item's position within -- in this case > -- the author group. > > I have this template: > > <xsl:template match="mods:modsCollection" mode="sort_author-year"> > <xsl:variable name="bibref" select="mods:mods" /> > <xsl:for-each-group select="$bibref" group-by="bib:grouping-key(.)"> > <xsl:sort select="current-grouping-key()"/> > <xsl:variable name="author-position" select="position()"/> > <xsl:variable name="shorten-author" as="xs:boolean" > select="$author-position > 1" /> > <xsl:for-each-group select="current-group()" > group-by="bib:year(.)"> > <xsl:sort select="current-grouping-key()" /> > <xsl:variable name="year"> > <xsl:value-of select="current-grouping-key()"/> > <xsl:if test="last() > 1"> > <xsl:number value="position()" format="a"/> > </xsl:if> > </xsl:variable> > <xsl:for-each select="current-group()"> > <xsl:apply-templates select="mods:titleInfo"> > <xsl:with-param name="year" select="$year"/> > <xsl:with-param name="shorten-author" > select="$shorten-author"/> > </xsl:apply-templates> > </xsl:for-each> > </xsl:for-each-group> > </xsl:for-each-group> > </xsl:template> > > The bib:grouping-key function constructs an author names string to sort. > > The problem is the author-position variable. > > What I want is for it to measure position within an author group. But > I'm getting these sorts of results: > > AUTHOR POSITION: 1 > SHORTEN: false > AUTHOR POSITION: 2 > SHORTEN: true > AUTHOR POSITION: 2 > SHORTEN: true > AUTHOR POSITION: 3 > SHORTEN: true > AUTHOR POSITION: 4 > SHORTEN: true > AUTHOR POSITION: 4 > SHORTEN: true > AUTHOR POSITION: 5 > SHORTEN: true > AUTHOR POSITION: 6 > > ... which tells me it's measuring the position of the group itself. > > What I'm wanting is: > > AUTHOR POSITION: 1 > SHORTEN: false > AUTHOR POSITION: 1 > SHORTEN: false > AUTHOR POSITION: 2 > SHORTEN: true > AUTHOR POSITION: 1 > SHORTEN: false > AUTHOR POSITION: 1 > SHORTEN: false > AUTHOR POSITION: 2 > SHORTEN: true > AUTHOR POSITION: 1 > SHORTEN: false > AUTHOR POSITION: 1 > SHORTEN: false > > How do I fix this? > > Bruce > > -- <M:D/> :: M. David Peterson :: XML & XML Transformations, C#, .NET, and Functional Languages Specialist
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] grouping/position problem, M. David Peterson | Thread | Re: [xsl] grouping/position problem, M. David Peterson |
[xsl] XSL-FO absolute position prob, Robert Hansson | Date | Re: [xsl] grouping/position problem, M. David Peterson |
Month |