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