#{} in xpath

P

Pen Ttt

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?
 
P

Phlip

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.
 
P

Phlip

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...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,371
Latest member
Brkaa

Latest Threads

Top