[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Number of elements with a given attribute


Subject: RE: [xsl] Number of elements with a given attribute
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Wed, 6 Jan 2010 07:17:43 -0000

When you do <xsl:for-each-group select="*">, you are selecting <role>
elements. No role element will ever match the pattern
"verse[@part='beginning']". I'm not sure, but I suspect you want to change
the select to select="role/verse".

Regards,

Michael Kay
http://www.saxonica.com/
http://twitter.com/michaelhkay

> -----Original Message-----
> From: J L [mailto:jinlii@xxxxxxxxxxx]
> Sent: 06 January 2010 01:51
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: RE: [xsl] Number of elements with a given attribute
>
>
> I'm new to XSLT 2.0. I tried this example in Altova and
> couldn't get the output below. I'm not sure if the input is
> wrong or my xsl is incorrect. Thanks for your time!
>  
> > <verse>
> >   <part role=3D"a">...</part>
> >   <part role=3D"a">...</part>
> >   <part role=3D"b">...</part>
> > </verse>
> > <verse>
>
> input xml:
> <verses>
>     <role name="a">
>         <verse>...</verse>
>         <verse part="beginning">1</verse>
>     </role>
>     <role name="a">
>         <verse part="continuation">continuation 2</verse>
>     </role>
>     <role name="b">
>         <verse part="continuation">continuation 3</verse>
>     </role>
>     <role name="b">
>         <verse part="end">end</verse>
>         <verse>...</verse>
>     </role>
>     <role name="a">
>         <verse>...</verse>
>         <verse part="beginning">1</verse>
>     </role>
>     <role name="a">
>         <verse part="continuation">continuation 2</verse>
>     </role>
>     <role name="b">
>         <verse part="continuation">continuation 3</verse>
>     </role>
>     <role name="b">
>         <verse part="end">end</verse>
>         <verse>...</verse>
>     </role>
> </verses>
>
> xsl:
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet version="2.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> xmlns:fo="http://www.w3.org/1999/XSL/Format"
> xmlns:xs="http://www.w3.org/2001/XMLSchema"
> xmlns:fn="http://www.w3.org/2005/xpath-functions">
>     <xsl:template match="verses">
>         <xsl:for-each-group select="*"
> group-starting-with="role/verse[empty(@part)] |
> verse[@part='beginning']">
>             <xsl:variable name="verse-number" select="position()"/>
>             <verse>
>                 <xsl:for-each select="current-group()">
>                     <part role="parent::role/@name">
>                         <xsl:copy-of select="node()"/>
>                     </part>
>                 </xsl:for-each>
>             </verse>
>         </xsl:for-each-group>
>     </xsl:template>
> </xsl:stylesheet>
>
> > From: mike@xxxxxxxxxxxx
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Date: Fri, 18 Dec 2009 09:45:18 +0000
> > Subject: RE: [xsl] Number of elements with a given attribute
> >
> >>
> >> In a piece of theater, I have some verses that are split between
> >> different roles.
> >>
> >> The other are tagged on the following model:
> >> <role name='...'>
> >>    ...
> >>   <verse>...</verse>
> >>   <verse part="beginning">...</verse> </role> <role name='...'>
> >>   <verse part="continuation">...</verse> </role> <role name='...'>
> >>   <verse part="continuation">...</verse> </role> <role name='...'>
> >>   <verse part="end">...</verse>
> >>   <verse>...</verse>
> >>   ...
> >> </role>
> >>
> >
> >> I wish to have the count of preceding parts of verse from the last
> >> beginning part.
> >> Regards,
> >
> > A classic case of two overlapping hierarchies running over
> the same data.
> > One of these hierarchies is represented directly in the XML tree
> > structure, the other is represented indirectly. You want to
> perform an
> > operation on the "hidden" hierarchy, so it's best to invert the
> > structure so the verse hierarchy becomes the primary one.
> That is, you want:
> >
> > <verse>
> >   <part role="a">...</part>
> >   <part role="a">...</part>
> >   <part role="b">...</part>
> > </verse>
> > <verse>
> >    ...
> >
> > which can be done like this:
> >
> > <xsl:for-each-group select="$verses"
> > group-starting-with="verse[empty(@part)] |
> verse[@part='beginning']">
> >   <xsl:variable name="verse-number" select="position()"/>
> >   <verse>
> >     <xsl:for-each select="current-group()">
> >       <part role="parent::role/@name">
> >         <xsl:copy-of select="node()"/>
> >       </part>
> >     </xsl:for-each>
> >   </verse>
> > </xsl:for-each-group>
> >
> > You now have each verse represented by a complete element,
> broken into
> > parts to show who speaks each part of the verse, and this makes it
> > easy for example to number the parts of a verse as you have
> asked for.
> >
> > Regards,
> >
> > Michael Kay
> > http://www.saxonica.com/
> > http://twitter.com/michaelhkay
> >
>
> _________________________________________________________________
> Hotmail: Powerful Free email with security by Microsoft.
> http://clk.atdmt.com/GBL/go/171222986/direct/01/


Current Thread
Keywords