Subject: Re: [xsl] position() returning incorrect results From: jon wa <jonni@xxxxxxxxx> Date: Thu, 14 Feb 2002 18:12:12 +0100 (MET) |
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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] position() returning inco, Jeni Tennison | Thread | [xsl] How to use xsl:key and xsl:so, Uslu, Cihan Y (MED) |
RE: [xsl] match on attribute anywhe, Bryan Rasmussen | Date | [xsl] differences between fop 0.20 , Bryan Rasmussen |
Month |