lib/xpath/renderer.rb in xpath-2.0.0 vs lib/xpath/renderer.rb in xpath-2.1.0

- old
+ new

@@ -36,55 +36,43 @@ def this_node '.' end - 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 + def descendant(current, element_names) + with_element_conditions("#{current}//", element_names) end - 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 + def child(current, element_names) + with_element_conditions("#{current}/", element_names) end - def axis(parent, name, tag_name) - "#{parent}/#{name}::#{tag_name}" + def axis(current, name, element_names) + with_element_conditions("#{current}/#{name}::", element_names) end - def node_name(current) - "name(#{current})" + def anywhere(element_names) + with_element_conditions("//", element_names) end def where(on, condition) "#{on}[#{condition}]" end def attribute(current, name) "#{current}/@#{name}" end - def equality(one, two) - "#{one} = #{two}" + def binary_operator(name, left, right) + "(#{left} #{name} #{right})" end def is(one, two) if @type == :exact - equality(one, two) + binary_operator("=", one, two) else - contains(one, two) + function(:contains, one, two) end end def variable(name) "%{#{name}}" @@ -92,14 +80,10 @@ def text(current) "#{current}/text()" end - def normalized_space(current) - "normalize-space(#{current})" - end - def literal(node) node end def css(current, selector) @@ -111,64 +95,22 @@ def union(*expressions) expressions.join(' | ') end - def anywhere(element_names) - if element_names.length == 1 - "//#{element_names.first}" - elsif element_names.length > 1 - "//*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]" - else - "//*" - end + def function(name, *arguments) + "#{name}(#{arguments.join(", ")})" end - def contains(current, value) - "contains(#{current}, #{value})" - end + private - def starts_with(current, value) - "starts-with(#{current}, #{value})" - end - - def and(one, two) - "(#{one} and #{two})" - end - - def or(one, two) - "(#{one} or #{two})" - end - - def one_of(current, values) - values.map { |value| "#{current} = #{value}" }.join(' or ') - end - - def next_sibling(current, element_names) + def with_element_conditions(expression, element_names) if element_names.length == 1 - "#{current}/following-sibling::*[1]/self::#{element_names.first}" + "#{expression}#{element_names.first}" elsif element_names.length > 1 - "#{current}/following-sibling::*[1]/self::*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]" + "#{expression}*[#{element_names.map { |e| "self::#{e}" }.join(" | ")}]" else - "#{current}/following-sibling::*[1]/self::*" + "#{expression}*" end - end - - 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 - - def inverse(current) - "not(#{current})" - end - - def string_function(current) - "string(#{current})" end end end