Re: [xsl] grouping/position problem

Subject: Re: [xsl] grouping/position problem
From: "M. David Peterson" <m.david.x2x2x@xxxxxxxxx>
Date: Fri, 22 Apr 2005 08:37:20 -0600
On 4/22/05, M. David Peterson <m.david.x2x2x@xxxxxxxxx> wrote:
> As I glanced over that stylesheet I realized I had forgot to take out
> the author template as I chose instead to place the authors name as an
> attribute of author-group.  Sorry for the confusion!  I also chose to
> dump the date processing  template to help empahsize that the best way
> to handle XML in this case is to
>
>
> <?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:apply-templates select="@year"/>
>        </item>
>    </xsl:template>
>    <xsl:template match="@year">
>        <xsl:attribute name="year">
>            <xsl:value-of select="."/>
>        </xsl:attribute>
>    </xsl:template>
> </xsl:stylesheet>
>
> On 4/22/05, M. David Peterson <m.david.x2x2x@xxxxxxxxx> wrote:
> > 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
> >
>
> --
> <M:D/>
>
> :: M. David Peterson ::
> XML & XML Transformations, C#, .NET, and Functional Languages Specialist
>


--
<M:D/>

:: M. David Peterson ::
XML & XML Transformations, C#, .NET, and Functional Languages Specialist

Current Thread