[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Xpath like syntax

Luke Galea

1/21/2005 6:22:00 AM

Hi all,

curious if there is a nice ruby way to express an xpath like navigation of an
object graph..

ie:

XPATH way:
Countries/Provinces/Cities[ @name = "London" ]

versus

The only Ruby way I can think of:
countries.collect{ |c| c.provinces.collect {|p| p.cities.select { |c2| c2#name
== 'London' } } }

Thanks in advance


17 Answers

tsawyer

1/21/2005 2:12:00 PM

0

Something like this certainly would be nice. Can you think of a nice
way to represent it in Ruby?

~trans.

Its Me

1/21/2005 3:02:00 PM

0

"Luke Galea" <lgalea@gmmsolutions.com> wrote in message

> curious if there is a nice ruby way to express an xpath like navigation of
an
> object graph..
>
> XPATH way:
> Countries/Provinces/Cities[ @name = "London" ]
>
> The only Ruby way I can think of:
> countries.collect{ |c| c.provinces.collect {|p| p.cities.select { |c2|
c2#name
> == 'London' } } }

How about :
x[:countries][:provinces][:cities, {:name=>"London"}]

You could build up a query by composing query objects. To evaluate the query
you would have to treat each sub-query as evaluating to a result-set of
tree-like things, I believe (modulo optimizations). Can probably build up a
filtering proc and use #each to avoid actually constructing the result set.

class Q
attr_accessor :chain
def initialize
self.chain = []
end
def [](attr=nil, hash={})
f = Q.new
f.chain = self.chain.dup
if attr
f.chain << [attr, hash]
else
f.chain.last << hash
end
f
end
end


require 'pp'
x = Q.new
pp x
y=x[:a]
pp y
z=y[:b][:c][:d, {:foo=>"bar", :baz=>"bratz"}]
pp z

#==>
#<Q:0x28a4668 @chain=[]>
#<Q:0x28bec90 @chain=[[:a, {}]]>
#<Q:0x28b8c90
@chain=[[:a, {}], [:b, {}], [:c, {}], [:d, {:foo=>"bar", :baz=>"bratz"}]]>


Nicholas Van Weerdenburg

1/21/2005 3:20:00 PM

0

On Fri, 21 Jan 2005 15:21:45 +0900, Luke Galea <lgalea@gmmsolutions.com> wrote:
> Hi all,
>
> curious if there is a nice ruby way to express an xpath like navigation of an
> object graph..
>
> ie:
>
> XPATH way:
> Countries/Provinces/Cities[ @name = "London" ]
>
> versus
>
> The only Ruby way I can think of:
> countries.collect{ |c| c.provinces.collect {|p| p.cities.select { |c2| c2#name
> == 'London' } } }
>
> Thanks in advance
>
>

I asked a similar question a couple of weeks ago, and there was
nothing existing in the ruby world from the looks of it.

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

Some external projects to look at mentioned:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

A code idea:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

JXpath in the Java world seems like it's for exactly this purpose.
http://jakarta.apache.org/commo...

I haven't worked on the query aspect of my project lately, so I
haven't made up my mind how I'm going to approach it yet.

Regards,
Nick
--
Nicholas Van Weerdenburg


Its Me

1/21/2005 4:42:00 PM

0


> x[:countries][:provinces][:cities, {:name=>"London"}]

You should treat [:countries], {:name=>"London"}... as convenient sugar for
a general case of a block at any query stage e.g.
x[:cities]{|c| c.population > c.houses.capacity.sum}[:streets]

And if you prefer "." syntax, you could use Jim Wierich's BlankSlate and
catch method_missing so x.cities does the same as x[:countries].

If you really get into this, you could do not just filtering (select/project
combinations), but create new nodes i.e. full transformations.


Aria Stewart

1/21/2005 4:48:00 PM

0

On Fri, 2005-01-21 at 15:21 +0900, Luke Galea wrote:
> Hi all,
>
> curious if there is a nice ruby way to express an xpath like navigation of an
> object graph..
>
> ie:
>
> XPATH way:
> Countries/Provinces/Cities[ @name = "London" ]

I was planning on implementing something like this this week!

Ari

----
Ruby web hosting? http://theinternetco.net/o...



tsawyer

1/21/2005 5:05:00 PM

0

itsme213 your Q class is promising.

Sometime ago I put out a small challenge to do R like querying and per
element processing. See ruby-talk:116415

http://groups-beta.google.com/group/comp.lang.ruby/browse_thread/thread/8f36cdeb04738c0e/788e64d6ca0dc746#788e64...

You'll notice Niklas Frykholm gave a nice solution which reminds me of
this. I haven't looked at the possibility in depth, but I wonder if
these two can be integrated? If you wanted to develop further I would
linke to include in upcoming Ruby Carats release.

Its Me

1/21/2005 6:02:00 PM

0


"trans." <tsawyer@gmail.com> wrote in message

> itsme213 your Q class is promising.
>
> Sometime ago I put out a small challenge to do R like querying and per
> element processing. See ruby-talk:116415
>
>
http://groups-beta.google.com/group/comp.lang.ruby/browse_thread/thread/8f36cdeb04738c0e/788e64d6ca0dc746#788e64...
>
> You'll notice Niklas Frykholm gave a nice solution

Yes, I'd do roughly what he did to evaluate the queries.
SomeObj # evaluate (query)

What I wrote previously was to compose the queries themselves as 1st-class
things.
Query # compose (queries)

Btw, my symbol and hash examples of queries
[:cities] {:name=>"London"}
were just sugar for blocks. Explicit blocks should be allowed too.
[:cities]{|c| c.size > c.population.size_need}
That would give your equivalent of list comprehensions.

Not sure if I can contribute anything complete, tho...

Does Ruby Carats do the same thing as Gabriele's extensions?



tsawyer

1/21/2005 6:24:00 PM

0

> Does Ruby Carats do the same thing as Gabriele's extensions?

Gabriele's? Do you mean Gavins? Or is this another set of extensions I
am not aware?

Ruby Facets is the extensions library, which is unique for its
atomicity.

Ruby Carats OTOH, is an extensive collection of Classes, Modules and
Mixins (but has not yet been released.)
See http://calibre.ruby...

tsawyer

1/21/2005 6:26:00 PM

0

> I was planning on implementing something like this this week!

Common wavelengths are amazing common around here :-)
Perhaps then you'd be interested in what I have suggested about buiding
a general purpose class for these use cases?

Its Me

1/21/2005 6:46:00 PM

0

"trans." <tsawyer@gmail.com> wrote in message

> Gabriele's? Do you mean Gavins?

My mistake. Yes, Gavins. Thanks for the clarification.