REXML bug - descendant-or-self selector

Discussion in 'Ruby' started by Gavin Kistner, Sep 4, 2005.

  1. 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
    }


    [Sliver:~/Desktop] gkistner$ ruby -v tmp.rb
    ruby 1.8.2 (2004-12-25) [powerpc-darwin7.7.2]
    <jim id='jim'/>
    <jam id='jam'/>
    <whee id='whee'/>
     
    Gavin Kistner, Sep 4, 2005
    #1
    1. Advertising

  2. 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
     
    Gavin Kistner, Sep 5, 2005
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ralf W. Grosse-Kunstleve
    Replies:
    16
    Views:
    623
    Lonnie Princehouse
    Jul 11, 2005
  2. Ralf W. Grosse-Kunstleve
    Replies:
    18
    Views:
    623
    Bengt Richter
    Jul 11, 2005
  3. Ralf W. Grosse-Kunstleve
    Replies:
    2
    Views:
    430
    Dan Sommers
    Jul 12, 2005
  4. falcon
    Replies:
    0
    Views:
    404
    falcon
    Jul 31, 2005
  5. Bart Kastermans
    Replies:
    6
    Views:
    425
    Bart Kastermans
    Jul 13, 2008
Loading...

Share This Page