#{} 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?

···

--
Posted via http://www.ruby-forum.com/.

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 09/12/2010 01:46 PM, Pen Ttt 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?

--
Anton Bangratz - Key ID 363474D1 - http://tony.twincode.net/
fortune(6):
Remembering is for those who have forgotten.
    -- Chinese proverb

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.

···

On Sep 12, 4:46 am, Pen Ttt <myocean...@yahoo.cn> wrote:

--
  Phlip
  http://zeekland.zeroplayer.com/

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 =&gt; str \} \)

to skip the 'namespaces' argument there...