xsl-list
[Top] [All Lists]

Re: preceding-sibling inside for-each appears to fail

2003-02-09 21:50:50
Wow... that did the trick, but I'm not sure I fully understand the positional predicate. As an experiment, I used the number "2" instead of the number "1" in the predicate just to see what would happen. Here is a fragment of the results:

<p>checking: accents_db</p>
<p>preceding sibling = </p>
<p>following sibling = accept_language</p>
<p>checking: accept_language</p>
<p>preceding sibling = </p>
<p>following sibling = add_anchors_to_excerpt</p>
<p>checking: add_anchors_to_excerpt</p>
<p>preceding sibling = accents_db</p>
<p>following sibling = allow_double_slash</p>
<p>checking: allow_double_slash</p>
<p>preceding sibling = accept_language</p>
<p>following sibling = allow_in_form</p>

As you can see, it took two iterations of the for-each loop before any results were returned by "preceding-sibling::attribute[2]/@name", which helps me understand, visually, what the "traversal" is consisting of (it reminds me of the history mechanism for accessing recent pages in JavaScript). Because this is the kind of person I am, I also tried running it with "-1" to see if, in fact, you could "reverse" the direction (and effectively reproduce the results of following-sibling). The results show that you can not:

<p>checking: accents_db</p>
<p>preceding sibling = </p>
<p>following sibling = accept_language</p>
<p>checking: accept_language</p>
<p>preceding sibling = </p>
<p>following sibling = add_anchors_to_excerpt</p>
<p>checking: add_anchors_to_excerpt</p>
<p>preceding sibling = </p>
<p>following sibling = allow_double_slash</p>
<p>checking: allow_double_slash</p>
<p>preceding sibling = </p>
<p>following sibling = allow_in_form</p>

What I'm having a little difficulty understanding is exactly why preceding-sibling, in this example, requires a positional predicate while following-sibling doesn't. Also, I thought that the node-set returned by the select attribute in the for-each element was complete. In other words, I thought that the select attribute function a little like a select statement in SQL and that the contents of the for-each element acted on the results of the select "statement", but the behavior demonstrated by this code implies that the resulting node-set is built during the loop and NOT as some internal mechanism fetching a "record set" (in MS terminology).

I think some of my difficulty understanding how this works stems from my background with other programming languages where the result of a function is returned at the end, and not during execution.

Thank you very much for your prompt (and accurate) reply. I am now able to proceed with my project (this had me stuck for a week).

Ted Stresen-Reuter

On Sunday, February 9, 2003, at 04:35  PM, Francis Norton wrote:

Hi Ted,

Ted Stresen-Reuter wrote:
...

<p>preceding sibling = <xsl:value-of select="preceding-sibling::attribute/@name" /></p>

...

As you can see, following-sibling successfully returns the following sibling, but preceding-sibling always returns the first node rather than the preceding-sibling node.

You need to remember two things here. First, XPath expressions normally return node-sets. Second, node-sets are processed in document order. So your select expression is returning the first member of the set "preceding-sibling::attribute/@name", which is always the first in document order. But if you put a positional predicate in as part of an XPath step then that is applied in the order of the current axis, so try

<p>preceding sibling = <xsl:value-of select="preceding-sibling::attribute[1]/@name" /></p>

Hope this helps -

Francis.


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



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