Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ngty/408365 to your computer and use it in GitHub Desktop.
Save ngty/408365 to your computer and use it in GitHub Desktop.
Single xpath for table cell matching
# This script shows how a single xpath can be used for matching a specific row in an html
# table, taking into account the the header text <th/> and cell text <td/>. It is able to
# handle case-sensitivity & nested inner text.
#
# Pls note that in order to test out case-sensitivity, u need to tweak IS_CASE_SENSITIVE &
# the html string.
#
# BTW, let me know how the generated xpath can be more elegant than it currently is.
#
require 'rubygems'
require 'nokogiri'
UPPERCASE_CHARS = ('A'..'Z').to_a.join('')
LOWERCASE_CHARS = ('a'..'z').to_a.join('')
IS_CASE_SENSITIVE = false
def t(string)
IS_CASE_SENSITIVE ? string : %\translate(#{string},"#{UPPERCASE_CHARS}","#{LOWERCASE_CHARS}")\
end
def qt(string)
t(%\"#{string}"\)
end
begin
puts \
"---------------------------------------------------------\n" +
"Expected Result: " + Nokogiri::HTML(<<-EOL
<html>
<body>
<table>
<tr><th><span>#</span></th><th><span>Na<br/>me</span></th><th>Gender</th></tr>
<tr><td>1</td><td>LL</td><td>Fem</br>ale</td></tr>
<tr><td>2</td><td>TY</td><td>Male</td></tr>
</table>
</body>
</html>
EOL
).xpath(
# NOTE: This is the part that generates the xpath !!
@path = '//table[.' +
[%w{# 1}, %w{Name LL}, %w{Gender Female}].inject([]) do |memo, arg|
field, value = arg
pos_cond = %\count(./ancestor::table[1]//th[#{t('normalize-space(.)')}=#{qt(field)}][1]/preceding-sibling::th)+1\
txt_cond = %\#{t('normalize-space(.)')}=#{qt(value)}\
memo << %\//td[#{pos_cond}][#{txt_cond}]\
end.join('/ancestor::tr[1]') + ']'
).text.split(/\s+/).to_s
puts [
"---------------------------------------------------------",
"Hurray !! We have a powerful XPATH builder that builds:",
"---------------------------------------------------------",
@path
].join("\n")
rescue
puts([
"---------------------------------------------------------",
"Yukes !! Something wrong with built XPATH:",
"---------------------------------------------------------",
@path
].join("\n"))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment