On Sep 3, 2005, at 11:51 PM, Gavin Kistner wrote:
> In XPath, "//" is an abbreviation for the "descendant-or-self"  
> selector. My understanding (and Microsoft's XPath implementation)  
> of this selector means that the following code should select the  
> bar element as well as the descendants.
>
> [Sliver:~/Desktop] gkistner$ cat tmp.rb
> xml = <<ENDXML
> <foo id="foo">
>         <bar id="bar">
>                 <jim id="jim" />
>                 <jam id="jam" />
>                 <bork><whee id="whee" /></bork>
>         </bar>
> </foo>
> ENDXML
>
> require 'rexml/document'
> include REXML
> bar = XPath.first( Document.new( xml ), '//bar' )
> bar.each_element( './/*[@id]' ){ |element_with_id|
>         puts element_with_id
> }

To set the record straight:
REXML is correct. My claim above (and what I believe is Microsoft's  
implementation) is incorrect.

The XPath expression:
     .//*[@id]
is XPath short-hand for:
     ./descendant-or-self::node()/child::*[attribute::id]

The implicit child:: axis is what causes the standard short-hand  
usage of // to act truly like a descendant selector. If you wanted  
the behavior that I describe above, then the legal XPath expression  
(which REXML supports) would be:
     .//self::*[@id]

Way to go Sean! Thanks for setting me straight. (I filed a bug  
report, and he kindly explained why I was wrong. I researched the  
matter with other web-based XPath tools[1] and confirmed my  
incorrectness.)

[1] Such as the oh-so-useful http://www.zvon.org:9001/saxon/cgi-bin/ 
XLab/XML/extras.html?stylesheetFile=XSLT%2FxpathAxes.xslt&value=%2FAAA 
%2FBBB%2F%2F*%5B%40id%5D