#{} in xpath

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?

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

On Sep 12, 4:46 am, Pen T. [email protected] 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.

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…