# \#{} in xpath

**URL:** <https://www.ruby-forum.com/t/in-xpath/194852>\
**Category:** Ruby\
**Created:** [September 12, 2010, 1:46pm UTC](https://www.ruby-forum.com/t/in-xpath/194852 "2010-09-12T13:46:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![luofeiyu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9de0a6/32.png) [@luofeiyu](https://www.ruby-forum.com/u/luofeiyu)\
**Post date:** [September 12, 2010, 1:46pm UTC](https://www.ruby-forum.com/t/in-xpath/194852/1 "2010-09-12T13:46:43Z")

</div>

code1  
data=doc.xpath(’.//small//span[@id=“yfs\_t10\_aacc”]’)  
puts data.text

code2  
str=“aacc”  
data=doc.xpath(’.//small//span[@id=“yfs\_t10\_#{str}”]’)  
puts data.text

code1 can work,code2 can’t,would you mind to tell me how to fix it?

---

<div class="post-metadata">

**Author:** ![luofeiyu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9de0a6/32.png) [@luofeiyu](https://www.ruby-forum.com/u/luofeiyu)\
**Post date:** [September 12, 2010, 2:08pm UTC](https://www.ruby-forum.com/t/in-xpath/194852/2 "2010-09-12T14:08:04Z")

</div>

On 09/12/2010 01:46 PM, Pen T. wrote:

> code1  
> data=doc.xpath(‘.//small//span[@id=“yfs\_t10\_aacc”]’)  
> puts data.text
> 
> code2  
> str=“aacc”  
> data=doc.xpath(‘.//small//span[@id=“yfs\_t10\_#{str}”]’)  
> puts data.text
> 
> code1 can work,code2 can’t,would you mind to tell me how to fix it?

Trick is that the string interpolation is not working with single  
quotes, but only with double quotes. Compare:

‘.//small//span[@id=“yfs\_t10\_#{str}”]’  
=\> “.//small//span[@id="yfs\_t10\_#{str}"]”

“.//small//span[@id="yfs\_t10\_#{str}"]”  
=\> “.//small//span[@id="yfs\_t10\_aacc"]”

Note the necessary escaping of the double quotes.

There’s also an alternative percent sign syntax for interpolated  
strings:

%{.//small//span[@id=“yfs\_t10\_#{str}”]}  
=\> “.//small//span[@id="yfs\_t10\_aacc"]”

Regards,

t.

PS: Helpful documentation:  
[http://en.wikibooks.org/wiki/Ruby\_Programming/Syntax/Literals](http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Literals)

---

<div class="post-metadata">

**Author:** ![luofeiyu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9de0a6/32.png) [@luofeiyu](https://www.ruby-forum.com/u/luofeiyu)\
**Post date:** [September 13, 2010, 3:35am UTC](https://www.ruby-forum.com/t/in-xpath/194852/3 "2010-09-13T03:35:55Z")

</div>

On Sep 12, 4:46 am, Pen T. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> code1  
> data=doc.xpath(‘.//small//span[@id=“yfs\_t10\_aacc”]’)

Firstly, // in some implementations differs from descendant:: , which  
is what you actually want. only use // to mean “forget the root, and  
give me all top-level small tags”. Some implementations would use the  
second // to go back to the root and search again for all spans, which  
is not what you want. I suspect REXML gets that “right”, but it’s a  
bad XPath habit to learn in general.

Next, you are not getting paid per keystroke, but that doesn’t mean  
your code can’t be readable. Try this:

data = doc.xpath(‘//small/descendant::span[@id = “yfs\_t10\_aacc”]’)

That formatting allows the eyes to rapidly find the point of  
everything, which is the yfs\_t10\_aacc.

> puts data.text
> 
> code2  
> str=“aacc”  
> data=doc.xpath(‘.//small//span[@id=“yfs\_t10\_#{str}”]’)

In Ruby, a single tick ’ introduces a simplistic string without #{}  
expanding, and without other goodies. Use ’ unless you need those  
goodies, then switch to “”. That gives this, with " on the inside:

data = doc.xpath(“//small/descendant::span[ @id =  
‘yfs\_t10\_#{ str }’ ]”)

I put spaces around the str partly for more readability, and partly to  
irritate the memory of a supervisor who requested I not do that. I’m  
visually challenged, so every little bit helps!

Next, sometimes in xpath land you need to inject strings containing ’  
or " or other shenanigans. Then you need an xpath expander, not a Ruby  
string expander. I SUSPECT you do that like this:

doc.xpath( ‘//small/descendant::span[@id = “yfs\_t10\_$str”]’,  
variables={ :str =\> str } )

Notice I dropped back to ’ ticks on the outside of the string.

---

<div class="post-metadata">

**Author:** ![luofeiyu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9de0a6/32.png) [@luofeiyu](https://www.ruby-forum.com/u/luofeiyu)\
**Post date:** [September 13, 2010, 7:15am UTC](https://www.ruby-forum.com/t/in-xpath/194852/4 "2010-09-13T07:15:59Z")

</div>

> Next, sometimes in xpath land you need to inject strings containing ’  
> or " or other shenanigans. Then you need an xpath expander, not a Ruby  
> string expander. I SUSPECT you do that like this:

that might need a

> doc.xpath( ‘//small/descendant::span[@id = “yfs\_t10\_$str”]’,

nil,

> ```
> { :str => str } )
> 
> ```

to skip the ‘namespaces’ argument there…
