# Xpath

**URL:** <https://www.ruby-forum.com/t/xpath/160275>\
**Category:** Ruby\
**Created:** [February 13, 2009, 5:10pm UTC](https://www.ruby-forum.com/t/xpath/160275 "2009-02-13T17:10:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![palberto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7ea924/32.png) [@palberto](https://www.ruby-forum.com/u/palberto)\
**Post date:** [February 13, 2009, 5:10pm UTC](https://www.ruby-forum.com/t/xpath/160275/1 "2009-02-13T17:10:17Z")

</div>

Hi all,

I have a question:

I would like to know if it is possible, using REXML, get full path from  
root, of document XML, to leaf node, through a XPath query?

example with l’XML:

 ... 

Xpath: //terzo[@id=‘3’]

Output:  
//primo/secondo/terzo[id=‘3’]

Thank’s in advance!  
Alberto

---

<div class="post-metadata">

**Author:** ![palberto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7ea924/32.png) [@palberto](https://www.ruby-forum.com/u/palberto)\
**Post date:** [February 13, 2009, 6:41pm UTC](https://www.ruby-forum.com/t/xpath/160275/2 "2009-02-13T18:41:13Z")

</div>

Alberto Alberto wrote:

> Xpath: //terzo[@id=‘3’]
> 
> Output:  
> /primo/secondo/terzo[id=‘3’]

You meant / not //.

Try this:

REXML::XPath(doc, “//terzo[@id=‘3’]”).xpath

That’s off the top of my head; advise me if it didn’t work! I know  
there’s a  
.xpath or .path in there somewhere…

(And I suspect Nokogiri provides a better XML ride!)

---

<div class="post-metadata">

**Author:** ![palberto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7ea924/32.png) [@palberto](https://www.ruby-forum.com/u/palberto)\
**Post date:** [February 13, 2009, 6:47pm UTC](https://www.ruby-forum.com/t/xpath/160275/3 "2009-02-13T18:47:57Z")

</div>

Alberto Alberto wrote:

> I would like to know if it is possible, using REXML, get full path from  
> root, of document XML, to leaf node, through a XPath query?
> 
> example with l’XML:
> 
> ... 
> 
> Xpath: //terzo[@id=‘3’]
> 
> Output:  
> //primo/secondo/terzo[id=‘3’]

Is that really considered XML?

require “rexml/document”  
include REXML

xml = \<\<TO\_END\_OF\_XML  
  
  
  
  
  
  
…

 TO\_END\_OF\_XML

doc = Document.new xml

target = “//terzo[@id=‘3’]”  
paths = []

XPath.each(doc, target) do |element|  
parents = []

while true  
parent = element.parent  
break if parent.name == “”

```
parents << parent.name
element = parent

```

end

path = parents.reverse.join(’/’)  
paths \<\< “//#{path}#{target[1…-1]}”  
end

puts \*paths

–output:–  
//primo/secondo/terzo[@id=‘3’]  
//primo/terzo[@id=‘3’]

---

<div class="post-metadata">

**Author:** ![palberto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7ea924/32.png) [@palberto](https://www.ruby-forum.com/u/palberto)\
**Post date:** [February 13, 2009, 7:03pm UTC](https://www.ruby-forum.com/t/xpath/160275/4 "2009-02-13T19:03:02Z")

</div>

Phlip wrote:

> Try this:
> 
> REXML::XPath(doc, “//terzo[@id=‘3’]”).xpath
> 
> That’s off the top of my head; advise me if it didn’t work! I know  
> there’s a  
> .xpath or .path in there somewhere…

When I output element.xpath, I get:

/primo/secondo/terzo  
/primo/terzo

---

<div class="post-metadata">

**Author:** ![palberto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7ea924/32.png) [@palberto](https://www.ruby-forum.com/u/palberto)\
**Post date:** [February 13, 2009, 7:05pm UTC](https://www.ruby-forum.com/t/xpath/160275/5 "2009-02-13T19:05:50Z")

</div>

> REXML::XPath(doc, “//terzo[@id=‘3’]”).xpath

Actually XPath.first

But I just tested that (indirectly), and the xpath accessor worked.

---

<div class="post-metadata">

**Author:** ![palberto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7ea924/32.png) [@palberto](https://www.ruby-forum.com/u/palberto)\
**Post date:** [February 16, 2009, 12:13pm UTC](https://www.ruby-forum.com/t/xpath/160275/6 "2009-02-16T12:13:13Z")

</div>

7stud – wrote:

> Alberto Alberto wrote:
> 
> > I would like to know if it is possible, using REXML, get full path from  
> > root, of document XML, to leaf node, through a XPath query?
> > 
> > example with l’XML:
> > 
> > ... 
> > 
> > Xpath: //terzo[@id=‘3’]
> > 
> > Output:  
> > //primo/secondo/terzo[id=‘3’]
> 
> Is that really considered XML?
> 
> require “rexml/document”  
> include REXML
> 
> xml = \<\<TO\_END\_OF\_XML  
>   
>   
>   
>   
>   
>   
> …
> 
> TO\_END\_OF\_XML
> 
> doc = Document.new xml
> 
> target = “//terzo[@id=‘3’]”  
> paths = []
> 
> XPath.each(doc, target) do |element|  
> parents = []
> 
> while true  
> parent = element.parent  
> break if parent.name == “”
> 
> ```
> parents << parent.name
> element = parent
> 
> ```
> 
> end
> 
> path = parents.reverse.join(’/’)  
> paths \<\< “//#{path}#{target[1…-1]}”  
> end
> 
> puts \*paths
> 
> –output:–  
> //primo/secondo/terzo[@id=‘3’]  
> //primo/terzo[@id=‘3’]

I try this solution and it works, but now my question is after operation  
parents \<\< parent.name

over parents array can I obtain a value of attributes with someting like  
this?

```
    .attributes.each_attribute {|attr|
p attr.expanded_name+" => "+attr.value

```

}

Thank’s a lot for quickly support.  
Alberto
