From: "Jesús Gabriel y Galán" Date: 2011-04-02T02:19:38+09:00 Subject: Re: Can you search in REXML by attributes? On Fri, Apr 1, 2011 at 6:27 PM, Kyle X. wrote: > Robert K. wrote in post #990336: >> On Fri, Apr 1, 2011 at 2:53 AM, Kyle X. wrote: >> >> It is not entirely clear what you want.  Do you want to look for all >> "ref" instances and find elements they are referring to?  Or do you >> want to do some kind of graph traversal where you start with a >> particular element and follow every ref attribute? > > Hi and thank you for your help.  I am sorry if what I wrote was unclear. > What my goal is is to start at a given location (in this case- > ) and eventually grab the three > IfcLengthMeasure text values, that are associated with this > , and put them into an array. > >> If the latter you can for example do a BFS. >> >> 10:11:30 Temp$ ./rx.rb >> --- VISIT: >> >>   >>     >>   >> >> --- VISIT: >> >>   >>    117.4 >>    119.7 >>    0. >>   >> >> 10:11:43 Temp$ cat -n rx.rb >>      1  #!/bin/env ruby19 >>      2 >>      3  require 'rexml/document' >>      4 >>      5  doc = REXML::Document.new(DATA.read) >>      6 >>      7  # BFS >>      8  queue = %w{i1671} >>      9 >>     10  until queue.empty? >>     11    id = queue.shift >>     12 >>     13    REXML::XPath.each(doc, "//*[@id='#{id}']") do |e| >>     14      puts "--- VISIT:", e >>     15 >>     16      REXML::XPath.each(e, './/*[@ref]') do |child| >>     17        next_id = child.attribute('ref') and queue.push(next_id) >>     18      end >>     19    end >>     20  end >>     21 >>     22  __END__ >>     23   >>     24   >>     25   >>     26     >>     27   >>     28   >>     29 >>     30   >>     31   >>     32     >>     33   >>     34   >>     35 >>     36   >>     37   >>     38     117.4 >>     39     119.7 >>     40     0. >>     41   >>     42   >>     43   >> 10:11:47 Temp$ > > I will give this a try. > >> >> Kind regards >> >> robert > > Dear 7stud.  Using the XPath command: > > doc = Document.new xml > target = XPath.match(doc, "//*[@id = 'i1671']") > p target > > It produces the following output as you said it would. > --output:-- > [ ... ] > > But I cannot figure out how to do anything with this from here to get to > the next point, and eventually be able to grab the three values. I usually use Nokogiri to handle XML documents, and find css selectors easier than XPath. I'd do it like this: doc = Nokogiri::XML(< 117.4 119.7 0. END ) reference = doc.css("#i1671 Location IfcCartesianPoint").attribute("ref").value doc.css("##{reference} Coordinates IfcLengthMeasure").map {|element| element.text} This returns: => ["117.4", "119.7", "0."] I'm pretty sure it's easy to translate these two expressions to XPath, something like: reference = REXML::XPath.first(doc, "//*[@id='i1671']/Location/IfcCartesianPoint").attribute("ref").value elements = REXML::XPath.match(doc, "//*[@id='#{reference}']/Coordinates/IfcLengthMeasure").map {|element| element.text} don't know if there's a better way, but the above works for me. Jesus.