Subject: Re: [xsl] Unexpected Context Node at Points in XPath Expression|
From: "Michael Terry" <formido@xxxxxxxxx>
Date: Tue, 4 Sep 2007 17:44:56 -0700
Awesome, thanks very much. It's quite clear. Offhand I can't verify whether my production tools (a so-called scripting addition for AppleScript, by Satimage) use XSLT 2.0. I'll check it out tonight. - mt On 9/4/07, Abel Braaksma <abel.online@xxxxxxxxx> wrote: > Michael Terry wrote: > >> I should look more carefully: the link that my mailprog (thunderbird) > >> makes of it does not include the trailing dot (as normally a link > >> wouldn't end on any and the dot it part of the sentence). Anyway, I see > >> now that the other page *is* different and does contain <h2> tags. And > >> now both queries select something (and different things). Sorry for my > >> first mistaken interpretation of your queries... > >> > >> -- Abel Braaksma > >> > >> > >> > > > > I think I misunderstood what becomes the context node. Take the first > > one I mentioned: > > > > id('bodyContent')/h2/following-sibling::*[position()<count(following::p/preceding-sibling::*) > > - count(preceding-sibling::*)] > > > > I thought that while the position() filter was running, 'h2' would > > be the context node. Instead, it seems the result of > > 'following-sibling::*' is the context node? What, does it change the > > context node to each item in that set as it applies the filter? I > > don't suppose there's a way to refer to the previous context node in a > > relative way, is there? > > In XSLT 2.0, your expression could be shortened to something like this: > > div/h2/following-sibling::*[. << > ../h2/following-sibling::p] > > or the inverse, meaning the same: > > $input/div/h2/following-sibling::p/preceding-sibling::*[. >> > ../h2] > > the operator >> or << (here <<) means "after" and "before" > respectively. If you are stuck with XSLT 1.0 (I hope not, 2.0 is so much > more fun) but, here you go: > > div/h2/following-sibling::ul > [generate-id(following-sibling::p) = > generate-id(../h2/following-sibling::p)] > > This is more readable and understandable if written also for XSLT 2.0: > > div/h2/following-sibling::ul > [following-sibling::p is ../h2/following-sibling::p] > > What we actually do here is selecting the stop-point (the P element) > from two perspectives: from the parent (naive implementation would do > ../p, but there are more P around, so we need to check it relative, > following, to our h2, hence: ../h2/following-sibling) and > holding every next P element (following-sibling::p) against it for > identity comparison. > > Identity comparison is done in XSLT 2.0 with the 'is' operator. In XSLT > 1.0 you have to pull a 'trick' with the generate-id() function which is > guaranteed to output a different identifier string for each node in the > input tree. > > Hope this makes it more clear to you. > > Cheers, > -- Abel Braaksma > > PS: when you use functions like generate-id(), you cannot use it inside > the XPath Checker, you can only do it inside an XSLT file. The XPath > checker gives an error, probably because it is an XSLT function and not > an XPath function. And of course, XPath checker cannot deal with XSLT > 2.0, use the open source Saxon, Gestalt or the free for personal use > AltovaXML for that.