RE: [xsl] counting nodes before a certain node

Subject: RE: [xsl] counting nodes before a certain node
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 1 Dec 2009 23:58:26 -0000
Right, so you don't actually want to count the nodes between the two book
elements, you only asked to count them because you thought that was a means
to an end?

I think what you probably want is something like

<xsl:template match="books">
  <xsl:for-each-group select="*" group-starting-with="book">
    <elem1>
      <xsl:copy-of select="current-group()/(book/title, notes)"/>
    </elem1>
  </xsl:for-each-group>
</xsl:template>

Regards,

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






> -----Original Message-----
> From: a kusa [mailto:akusa8@xxxxxxxxx]
> Sent: 01 December 2009 22:02
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] counting nodes before a certain node
>
> Hi
>
> Thank you for all your response. I am sorry that I haven't
> been able to express my problem clearly. I will try it again.
> What I need is this:
> My input:
> <books>
> <book>
> <title>First title</title>
> </book>
> <notes>The following books talk about history.</notes>
> <notes>For further information please log on to </notes>
> <notes>Thank you for choosing.. </notes> <book>
> <title>Abraham Lincoln </title> </book>
>
> <authors>
> sample data
>
> </authors>
> <notes>Please call... </notes>
> <notes>Copyright Information </notes>
> <book>
>
> sample data
> </book>
> </books>
>
> When I am in the template called book, I want to display all
> notes after the first book up to the second book element.
>
> So in my XSLT when I say:
>
> <xsl:template match="books">
> 		<xsl:apply-templates select="book"/>
> 	</xsl:template>
> 	<xsl:template match="book">
> 		<elem1>
> 			<title>
> 				<xsl:apply-templates select="title[1]"/>
> 			</title>
> 			<notes>
> 				<xsl:apply-templates
> select="following::notes[following-sibling::*[1][self::book]]"/>
> 			</notes>
> 		</elem1>
> 	</xsl:template>
>
> It selects only the last <notes> element and it selects both
> the notes elements right after <book> and after <author>.
> Output:
> <elem1>
> 	<title>First title</title>
> 	<notes>Thank you for choosing.. Copyright Information
> </notes> </elem1> <elem1>
> 	<title>Abraham Lincoln </title>
> 	<notes>Copyright Information </notes>
> </elem1>
> <elem1>
> 	<title/>
> 	<notes/>
> </elem1>
>
> My desired output is:
>
> <elem1>
> 	<title>First title</title>
> 	<notes>The following books talk about history.For
> further information please log on to. Thank you for
> choosing..  </notes> </elem1> <elem1>
> 	<title>Abraham Lincoln </title>
> 	<notes>Please call... Copyright Information </notes>
> </elem1> <elem1>
> 	<title/>
> 	<notes/>
> </elem1>
>
> Please let me know if I am more clear now.
>
>
>
> On Mon, Nov 30, 2009 at 6:01 PM, Wendell Piez
> <wapiez@xxxxxxxxxxxxxxxx> wrote:
> > Hi,
> >
> > At 06:02 PM 11/30/2009, Mike wrote:
> >>
> >> Given XSLT 2.0, you can select two elements $a and $b, and
> then the
> >> number of elements between these two is
> >>
> >> count($b/preceding-sibling::*) - count($b/preceding-sibling::*) - 1
> >>
> >> This is probably more efficient than
> >>
> >> count(*[. >> $a and $b >> .])
> >>
> >> but you can use that if it's more convenient.
> >
> > This answers the question as posed.
> >
> > A better solution, however, might be available if you
> specified your
> > count differently.
> >
> > For example, you might be better off asking "how do I count notes
> > elements that do not have book or author element
> ancestors", or "how
> > do I count notes elements that are directly inside books, but not
> > deeper". (From your problem statement it's impossible to
> know whether
> > one of these might not be the
> > case.)
> >
> > Cheers,
> > Wendell
> >
> >> > -----Original Message-----
> >> > From: a kusa [mailto:akusa8@xxxxxxxxx]
> >> > Sent: 30 November 2009 22:40
> >> > To: xsl-list
> >> > Subject: [xsl] counting nodes before a certain node
> >> >
> >> > Hi
> >> >
> >> > How do I count nodes up to a certain point in XSLT?
> >> >
> >> > Example:
> >> >
> >> > My xml file looks like this:
> >> >
> >> > <books>
> >> > <book>
> >> > <title>First title</book>
> >> > </book>
> >> > <notes>The following books talk about history.</notes>
> <notes>For
> >> > further information please log on to </notes>
> <notes>Thank you for
> >> > choosing.. </notes> <book> <title>Abraham Lincoln
> </title> </book>
> >> >
> >> > <authors>
> >> > sample data
> >> >
> >> > </authors>
> >> > <notes>Please call... </notes>
> >> > <notes>Copyright Information </notes> <book>
> >> >
> >> > sample data
> >> > </book>
> >> > </books>
> >> >
> >> > In my XSLT file, I want to count all <notes> just before
> the second
> >> > <book> element but immediately after the first book
> element or just
> >> > after <authors>.
> >> >
> >> > How do I count all the notes elements here?
> >
> >
> >
> ======================================================================
> > Wendell Piez                            
> mailto:wapiez@xxxxxxxxxxxxxxxx
> > Mulberry Technologies, Inc.                
> http://www.mulberrytech.com
> > 17 West Jefferson Street                    Direct Phone:
> 301/315-9635
> > Suite 207                                          Phone:
> 301/315-9631
> > Rockville, MD  20850                                 Fax:
> 301/315-8285
> >
> ----------------------------------------------------------------------
> >  Mulberry Technologies: A Consultancy Specializing in SGML and XML
> >
> ======================================================================

Current Thread