On Fri, Apr 1, 2011 at 2:53 AM, Kyle X. <haebooty / yahoo.com> wrote:
> Hello and thank you to all the wonderful and helpful people at this
> forum. =A0I am trying to figure out how to search through an XML file and
> grab information. =A0I have been reading the REXML tutorials but could no=
t
> see an answer to my problem in them
> (http://www.germane-software.com/software/rexml/docs/tutorial.html).
> The problem is I need to search by an attribute (in this case the ref)
> and cannot figure out how. =A0Here is a snippet of the XML I am trying to
> extract information from:
>
> <IfcWallStandardCase id=3D"i1677">
> =A0<ObjectPlacement>
> =A0 =A0<IfcLocalPlacement xsi:nil=3D"true" ref=3D"i1671"/>
> =A0</ObjectPlacement>
> </IfcWallStandardCase>
>
> <IfcAxis2Placement3D id=3D"i1671">
> =A0<Location>
> =A0 =A0<IfcCartesianPoint xsi:nil=3D"true" ref=3D"i1667"/>
> =A0</Location>
> </IfcAxis2Placement3D>
>
> <IfcCartesianPoint id=3D"i1667">
> =A0<Coordinates id=3D"i1670" exp:cType=3D"list">
> =A0 =A0<IfcLengthMeasure exp:pos=3D"0">117.4</IfcLengthMeasure>
> =A0 =A0<IfcLengthMeasure exp:pos=3D"1">119.7</IfcLengthMeasure>
> =A0 =A0<IfcLengthMeasure exp:pos=3D"2">0.</IfcLengthMeasure>
> =A0</Coordinates>
> </IfcCartesianPoint>
>
> So basically I have to start with IfcWallStandardCase and from there
> work my way through the "ref"'s until I get to the 3 IfcLengthMeasures.
> I know how to grab the first ref "i1671" using:
> =A0XPath.match(doc,"/IfcWallStandardCase/ObjectPlacement/IfcLocalPlacemen=
t")
> and some additional code.
>
> My problem is I cannot figure out how to use this "i1671" to search the
> xml and grab the next ref. =A0This ref is the only thing linking the item=
s
> together, so it is the only thing that I can use.
>
> Is it possible to search a document by using an attribute, and if so
> how? In this case to use the ref, "i1671" to search the document for
> where it is used as id=3D"i1671" so I can grab the next ref from there an=
d
> so on. =A0Any help would be greatly appreciated.

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?

If the latter you can for example do a BFS.

10:11:30 Temp$ ./rx.rb
--- VISIT:
<IfcAxis2Placement3D id=3D'i1671'>
 <Location>
   <IfcCartesianPoint xsi:nil=3D'true' ref=3D'i1667'/>
 </Location>
</IfcAxis2Placement3D>
--- VISIT:
<IfcCartesianPoint id=3D'i1667'>
 <Coordinates exp:cType=3D'list' id=3D'i1670'>
   <IfcLengthMeasure exp:pos=3D'0'>117.4</IfcLengthMeasure>
   <IfcLengthMeasure exp:pos=3D'1'>119.7</IfcLengthMeasure>
   <IfcLengthMeasure exp:pos=3D'2'>0.</IfcLengthMeasure>
 </Coordinates>
</IfcCartesianPoint>
10:11:43 Temp$ cat -n rx.rb
     1  #!/bin/env ruby19
     2
     3  require 'rexml/document'
     4
     5  doc =3D REXML::Document.new(DATA.read)
     6
     7  # BFS
     8  queue =3D %w{i1671}
     9
    10  until queue.empty?
    11    id =3D queue.shift
    12
    13    REXML::XPath.each(doc, "//*[@id=3D'#{id}']") do |e|
    14      puts "--- VISIT:", e
    15
    16      REXML::XPath.each(e, './/*[@ref]') do |child|
    17        next_id =3D child.attribute('ref') and queue.push(next_id)
    18      end
    19    end
    20  end
    21
    22  __END__
    23  <root xmlns:exp=3D"http://foo" xmlns:xsi=3D"http://bar">
    24  <IfcWallStandardCase id=3D"i1677">
    25   <ObjectPlacement>
    26     <IfcLocalPlacement xsi:nil=3D"true" ref=3D"i1671"/>
    27   </ObjectPlacement>
    28  </IfcWallStandardCase>
    29
    30  <IfcAxis2Placement3D id=3D"i1671">
    31   <Location>
    32     <IfcCartesianPoint xsi:nil=3D"true" ref=3D"i1667"/>
    33   </Location>
    34  </IfcAxis2Placement3D>
    35
    36  <IfcCartesianPoint id=3D"i1667">
    37   <Coordinates id=3D"i1670" exp:cType=3D"list">
    38     <IfcLengthMeasure exp:pos=3D"0">117.4</IfcLengthMeasure>
    39     <IfcLengthMeasure exp:pos=3D"1">119.7</IfcLengthMeasure>
    40     <IfcLengthMeasure exp:pos=3D"2">0.</IfcLengthMeasure>
    41   </Coordinates>
    42  </IfcCartesianPoint>
    43  </root>
10:11:47 Temp$

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
IyEvYmluL2VudiBydWJ5MTkKCnJlcXVpcmUgJ3JleG1sL2RvY3VtZW50JwoKZG9jID0gUkVYTUw6
OkRvY3VtZW50Lm5ldyhEQVRBLnJlYWQpCgojIEJGUwpxdWV1ZSA9ICV3e2kxNjcxfQoKdW50aWwg
cXVldWUuZW1wdHk/CiAgaWQgPSBxdWV1ZS5zaGlmdAoKICBSRVhNTDo6WFBhdGguZWFjaChkb2Ms
ICIvLypbQGlkPScje2lkfSddIikgZG8gfGV8CiAgICBwdXRzICItLS0gVklTSVQ6IiwgZQoKICAg
IFJFWE1MOjpYUGF0aC5lYWNoKGUsICcuLy8qW0ByZWZdJykgZG8gfGNoaWxkfAogICAgICBuZXh0
X2lkID0gY2hpbGQuYXR0cmlidXRlKCdyZWYnKSBhbmQgcXVldWUucHVzaChuZXh0X2lkKQogICAg
ZW5kCiAgZW5kCmVuZAoKX19FTkRfXwo8cm9vdCB4bWxuczpleHA9Imh0dHA6Ly9mb28iIHhtbG5z
OnhzaT0iaHR0cDovL2JhciI+CjxJZmNXYWxsU3RhbmRhcmRDYXNlIGlkPSJpMTY3NyI+CiA8T2Jq
ZWN0UGxhY2VtZW50PgogICA8SWZjTG9jYWxQbGFjZW1lbnQgeHNpOm5pbD0idHJ1ZSIgcmVmPSJp
MTY3MSIvPgogPC9PYmplY3RQbGFjZW1lbnQ+CjwvSWZjV2FsbFN0YW5kYXJkQ2FzZT4KCjxJZmNB
eGlzMlBsYWNlbWVudDNEIGlkPSJpMTY3MSI+CiA8TG9jYXRpb24+CiAgIDxJZmNDYXJ0ZXNpYW5Q
b2ludCB4c2k6bmlsPSJ0cnVlIiByZWY9ImkxNjY3Ii8+CiA8L0xvY2F0aW9uPgo8L0lmY0F4aXMy
UGxhY2VtZW50M0Q+Cgo8SWZjQ2FydGVzaWFuUG9pbnQgaWQ9ImkxNjY3Ij4KIDxDb29yZGluYXRl
cyBpZD0iaTE2NzAiIGV4cDpjVHlwZT0ibGlzdCI+CiAgIDxJZmNMZW5ndGhNZWFzdXJlIGV4cDpw
b3M9IjAiPjExNy40PC9JZmNMZW5ndGhNZWFzdXJlPgogICA8SWZjTGVuZ3RoTWVhc3VyZSBleHA6
cG9zPSIxIj4xMTkuNzwvSWZjTGVuZ3RoTWVhc3VyZT4KICAgPElmY0xlbmd0aE1lYXN1cmUgZXhw
OnBvcz0iMiI+MC48L0lmY0xlbmd0aE1lYXN1cmU+CiA8L0Nvb3JkaW5hdGVzPgo8L0lmY0NhcnRl
c2lhblBvaW50Pgo8L3Jvb3Q+Cg==