Xpath to attributes

Discussion in 'Ruby' started by listrecv@gmail.com, Feb 22, 2006.

  1. Guest

    Is there anyway to do generic xpath's, for both elements and attributes
    (ie //customer/phone/@type --> "home")? REXML can do xpath to fetch
    elements (rexml_element.text('//customer/phone')) but can't seem to use
    xpath to find attributes.
     
    , Feb 22, 2006
    #1
    1. Advertising

  2. Ross Bamford Guest

    Re: [OT] Xpath to attributes

    On Wed, 2006-02-22 at 10:33 +0900, wrote:
    > Is there anyway to do generic xpath's, for both elements and attributes
    > (ie //customer/phone/@type --> "home")? REXML can do xpath to fetch
    > elements (rexml_element.text('//customer/phone')) but can't seem to use
    > xpath to find attributes.


    d = REXML::Document.new <<EOX
    <customer>
    <phone type='home'>0115</phone>
    <phone type='mobi'>07807</phone>
    </customer>
    EOX

    m = REXML::XPath.match(d, '//customer/phone[@type = "home"]')
    p m.to_s
    # => <phone type='home'>0115</phone>

    --
    Ross Bamford -
     
    Ross Bamford, Feb 22, 2006
    #2
    1. Advertising

  3. wrote:
    > Is there anyway to do generic xpath's, for both elements and attributes
    > (ie //customer/phone/@type --> "home")? REXML can do xpath to fetch
    > elements (rexml_element.text('//customer/phone')) but can't seem to use
    > xpath to find attributes.


    class Array; alias atr first; alias txt last end
    class String
    def xtag(s)
    scan( %r!
    < #{s} (?: \s+ ( [^>]* ) )? / >
    |
    < #{s} (?: \s+ ( [^>]* ) )? >
    ( .*? ) </ #{s} >
    !mx ).
    map{ |unpaired, attr, data| h = { }
    attr = ( unpaired || attr )
    if attr
    attr.scan( %r! ( \S+ ) = ( ["'] ) ( .*? ) \2 !x ){ |k,q,v|
    h[k] = v }
    end
    [ h, data ]
    }
    end
    def xpath(s)
    s.scan(%r! [^/"]+ (?: "[^"]*" )? !x).inject([[nil,self]]){|ary,str|
    if "@" == str[0,1]
    str =~ /@(.*?)="(.*)"/
    ary.select{|a,t| a[$1] == $2 }
    else
    return [] if [] == ary
    ary[0].txt.xtag(str)
    end
    }
    end
    end


    p DATA.read.xpath('customer/@loc="south"/phone/@type="mobi"')


    __END__
    <customer loc="north">
    <phone type='home'>0115</phone>
    <phone type='mobi'>07807</phone>
    </customer>
    <customer loc="south">
    <phone type='home'>0319</phone>
    <phone type='mobi'>09802</phone>
    </customer>
     
    William James, Feb 23, 2006
    #3
  4. Guest

    Thanks.

    But I'd like to just extract the attribute value via Xpath.

    If my Xpath is correct, I could just do '//customer/phone/@type' to get
    'home'. Is there any way I can do this in Ruby?
     
    , Feb 24, 2006
    #4
  5. wrote:
    > Thanks.
    >
    > But I'd like to just extract the attribute value via Xpath.
    >
    > If my Xpath is correct, I could just do '//customer/phone/@type' to get
    > 'home'. Is there any way I can do this in Ruby?



    p DATA.read.xchain('customer/@loc="south"/phone').first.atr['type']

    __END__
    <customer loc="north">
    <phone type='home'>0115</phone>
    <phone type='mobi'>07807</phone>
    </customer>
    <customer loc="south">
    <phone type='home'>0319</phone>
    </customer>


    The rest:

    class Array; alias atr first; alias txt last end
    class String
    def xtag(s)
    result = []
    scan( %r!
    < #{s} (?: \s+ ( [^>]* ) )? / >
    |
    < #{s} (?: \s+ ( [^>]* ) )? >
    ( .*? ) </ #{s} >
    !mx ) \
    { |unpaired, attr, data| h = { }
    attr = ( unpaired || attr )
    attr.scan( %r{ ( \S+ ) = ( ["'] ) ( .*? ) \2 }x ){ |k,q,v|
    h[k] = v } if attr
    block_given? ? ( yield [ h, data ] ) : result << [ h, data ]
    }
    result
    end
    def xchain(s)
    s.scan(%r! [^/"]+ (?: "[^"]*" )? !x).inject([[nil,self]]){|ary,str|
    if "@" == str[0,1]
    str =~ /@(.*?)="(.*)"/
    ary.select{|a,t| a[$1] == $2 }
    else
    return [] if [] == ary
    ary[0].txt.xtag(str)
    end
    }
    end
    end
     
    William James, Feb 25, 2006
    #5
    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. Marvin_123456

    "Memory leak" in javax.xml.xpath.XPath

    Marvin_123456, Jul 29, 2005, in forum: Java
    Replies:
    4
    Views:
    1,994
    jan V
    Jul 29, 2005
  2. Alastair Cameron
    Replies:
    1
    Views:
    7,444
    SQL Server Development Team [MSFT]
    Jul 8, 2003
  3. Anna
    Replies:
    0
    Views:
    542
  4. goog
    Replies:
    0
    Views:
    518
  5. Tjerk Wolterink

    XPath: efficiency in xpath expressions

    Tjerk Wolterink, Nov 13, 2004, in forum: XML
    Replies:
    1
    Views:
    1,662
    Richard Tobin
    Nov 13, 2004
Loading...

Share This Page