class XPath::Renderer

Public Class Methods

render(node) click to toggle source
# File lib/xpath/renderer.rb, line 3
def self.render(node)
  new.render(node)
end

Public Instance Methods

and(one, two) click to toggle source
# File lib/xpath/renderer.rb, line 116
def and(one, two)
  "(#{one} and #{two})"
end
anywhere(tag_name) click to toggle source
# File lib/xpath/renderer.rb, line 104
def anywhere(tag_name)
  "//#{tag_name}"
end
attribute(current, name) click to toggle source
# File lib/xpath/renderer.rb, line 69
def attribute(current, name)
  "#{current}/@#{name}"
end
axis(parent, name, tag_name) click to toggle source
# File lib/xpath/renderer.rb, line 57
def axis(parent, name, tag_name)
  "#{parent}/#{name}::#{tag_name}"
end
child(parent, element_names) click to toggle source
# File lib/xpath/renderer.rb, line 47
def child(parent, element_names)
  if element_names.length == 1
    "#{parent}/#{element_names.first}"
  elsif element_names.length > 1
    "#{parent}/*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]"
  else
    "#{parent}/*"
  end
end
contains(current, value) click to toggle source
# File lib/xpath/renderer.rb, line 108
def contains(current, value)
  "contains(#{current}, #{value})"
end
convert_argument(argument) click to toggle source
# File lib/xpath/renderer.rb, line 12
def convert_argument(argument)
  case argument
    when Expression, Union then render(argument)
    when Array then argument.map { |element| convert_argument(element) }
    when String then string_literal(argument)
    when Literal then argument.value
    else argument.to_s
  end
end
css(current, selector) click to toggle source
# File lib/xpath/renderer.rb, line 93
def css(current, selector)
  paths = Nokogiri::CSS.xpath_for(selector).map do |xpath_selector|
    "#{current}#{xpath_selector}"
  end
  union(paths)
end
descendant(parent, element_names) click to toggle source
# File lib/xpath/renderer.rb, line 37
def descendant(parent, element_names)
  if element_names.length == 1
    "#{parent}//#{element_names.first}"
  elsif element_names.length > 1
    "#{parent}//*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]"
  else
    "#{parent}//*"
  end
end
equality(one, two) click to toggle source
# File lib/xpath/renderer.rb, line 73
def equality(one, two)
  "#{one} = #{two}"
end
inverse(current) click to toggle source
# File lib/xpath/renderer.rb, line 148
def inverse(current)
  "not(#{current})"
end
literal(node) click to toggle source
# File lib/xpath/renderer.rb, line 89
def literal(node)
  node
end
next_sibling(current, element_names) click to toggle source
# File lib/xpath/renderer.rb, line 128
def next_sibling(current, element_names)
  if element_names.length == 1
    "#{current}/following-sibling::*[1]/self::#{element_names.first}"
  elsif element_names.length > 1
    "#{current}/following-sibling::*[1]/self::*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]"
  else
    "#{current}/following-sibling::*[1]/self::*"
  end
end
node_name(current) click to toggle source
# File lib/xpath/renderer.rb, line 61
def node_name(current)
  "name(#{current})"
end
normalized_space(current) click to toggle source
# File lib/xpath/renderer.rb, line 85
def normalized_space(current)
  "normalize-space(#{current})"
end
one_of(current, values) click to toggle source
# File lib/xpath/renderer.rb, line 124
def one_of(current, values)
  values.map { |value| "#{current} = #{value}" }.join(' or ')
end
or(one, two) click to toggle source
# File lib/xpath/renderer.rb, line 120
def or(one, two)
  "(#{one} or #{two})"
end
previous_sibling(current, element_names) click to toggle source
# File lib/xpath/renderer.rb, line 138
def previous_sibling(current, element_names)
  if element_names.length == 1
    "#{current}/preceding-sibling::*[1]/self::#{element_names.first}"
  elsif element_names.length > 1
    "#{current}/preceding-sibling::*[1]/self::*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]"
  else
    "#{current}/preceding-sibling::*[1]/self::*"
  end
end
render(node) click to toggle source
# File lib/xpath/renderer.rb, line 7
def render(node)
  arguments = node.arguments.map { |argument| convert_argument(argument) }
  send(node.expression, *arguments)
end
starts_with(current, value) click to toggle source
# File lib/xpath/renderer.rb, line 112
def starts_with(current, value)
  "starts-with(#{current}, #{value})"
end
string_function(current) click to toggle source
# File lib/xpath/renderer.rb, line 152
def string_function(current)
  "string(#{current})"
end
string_literal(string) click to toggle source
# File lib/xpath/renderer.rb, line 22
def string_literal(string)
  if string.include?("'")
    string = string.split("'", -1).map do |substr|
      "'#{substr}'"
    end.join(%q{,"'",})
    "concat(#{string})"
  else
    "'#{string}'"
  end
end
text(current) click to toggle source
# File lib/xpath/renderer.rb, line 81
def text(current)
  "#{current}/text()"
end
this_node() click to toggle source
# File lib/xpath/renderer.rb, line 33
def this_node
  '.'
end
union(*expressions) click to toggle source
# File lib/xpath/renderer.rb, line 100
def union(*expressions)
  expressions.join(' | ')
end
variable(name) click to toggle source
# File lib/xpath/renderer.rb, line 77
def variable(name)
  "%{#{name}}"
end
where(on, condition) click to toggle source
# File lib/xpath/renderer.rb, line 65
def where(on, condition)
  "#{on}[#{condition}]"
end