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