This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: position() returning incorrect results


ah! damn whitespace :)

Thanks Jeni, i was loosing it there for a minute ;)

> Hi Jon,
> 
> > i just had an <xsl:apply-templates> to get the stylesheet to work on
> > an html like file, which just had lots of <p> tags for paragraphs in
> > it. when i do the <xsl:template match="p"> and then try to print the
> > position() it all goes wrong and seems to count up in twos. what
> > confuses me more is that if i have a seperate template for
> > <xsl:template match="p[1]"> it will correctly pick out the first
> > paragraph and report it's position() as being 1.
> 
> Yep, this is because the way position() works within a template is
> different from the way position() works within a pattern.
> 
> Within a pattern (in a match attribute), you actually test the
> position of a node amongst its siblings that are the same type as that
> node. So your pattern of p[1] gives you a template that matches the p
> elements that are the first p element children of their parent
> elements. It would match a p element whose only preceding sibling was
> a comment, or a text node, or a ul element.
> 
> Within a template, on the other hand, the position() function gives
> you the position of the node that you're processing with that template
> within the list of nodes that are currently being processed. That
> means that the position() of a node according to a template depends on
> the xsl:apply-templates that's used to apply the template. If, as is
> frequently the case, you use:
> 
>   <xsl:apply-templates />
> 
> then the position() of the node will be the position of the node
> amongst all its sibling nodes.
> 
> "But," I hear you wonder "the p elements that I'm applying templates
> to are the only children of their parent element anyway, so surely the
> first p element should have the position 1?"
> 
> And the answer would be "yes" if that were the case. But usually, and
> I'm guessing in your case, the elements actually have invisible
> siblings -- whitespace-only text nodes! Take the example:
> 
>   <div>
>     <p>...</p>
>     <p>...</p>
>   </div>
> 
> The div element actually has five children - a whitespace-only text
> node (giving a line break and some indentation), the first p element,
> another whitespace-only text node, the second p element, and a final
> whitespace-only text node.
> 
> There are two solutions to this predicament. The first solution is to
> only select the p elements when you apply templates:
> 
>   <xsl:apply-templates select="p" />
> 
> That way the node set only contains the nodes that you actually want
> to count.
> 
> The second solution is to strip out those pesky whitespace-only text
> nodes from the node tree, so that they're not counted anyway. You can
> do this by placing a xsl:strip-spaces directive at the top of your
> stylesheet. When I'm processing data-oriented XML (which doesn't
> include mixed content), I usually use:
> 
> <xsl:strip-space elements="*" />
> 
> To strip whitespace-only text nodes from all the elements in the
> document. You might want to be more careful, and only strip the
> whitespace-only text nodes from (say) the body and div elements, with:
> 
> <xsl:strip-space elements="body div" />
> 
> I hope that helps,
> 
> Jeni
> 
> ---
> Jeni Tennison
> http://www.jenitennison.com/
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 

-- 
GMX - Die Kommunikationsplattform im Internet.
http://www.gmx.net


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]