[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Xpath to attributes

List Recv

2/22/2006 1:32:00 AM

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.

5 Answers

Ross Bamford

2/22/2006 10:37:00 AM

0

On Wed, 2006-02-22 at 10:33 +0900, listrecv@gmail.com 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 - rosco@roscopeco.REMOVE.co.uk



William James

2/23/2006 4:07:00 AM

0

listrecv@gmail.com 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>

List Recv

2/24/2006 3:59:00 PM

0

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?

William James

2/25/2006 8:31:00 PM

0

listrecv@gmail.com 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

Liberal $500 million tax dollar disaster

9/1/2009 6:28:00 AM

0

Both radical leftists and Hitler shared one common thought; that the
absolute control over people's lives is desirable.