diff --git a/lib/oga.rb b/lib/oga.rb index 4143d8a..9c34495 100644 --- a/lib/oga.rb +++ b/lib/oga.rb @@ -31,3 +31,4 @@ require_relative 'oga/html/parser' require_relative 'oga/xpath/node' require_relative 'oga/xpath/lexer' require_relative 'oga/xpath/parser' +require_relative 'oga/xpath/evaluator' diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb new file mode 100644 index 0000000..b1ab513 --- /dev/null +++ b/lib/oga/xpath/evaluator.rb @@ -0,0 +1,51 @@ +module Oga + module XPath + ## + # The Evaluator class is used to evaluate an XPath expression in the + # context of a given document. + # + class Evaluator < AST::Processor + ## + # @param [Oga::XML::Document|Oga::XML::Node] document + # + def initialize(document) + @document = document + @cursor = @document + end + + def on_absolute(node) + if @cursor.is_a?(XML::Node) + @cursor = @cursor.root_node + end + + return process_all(node.children) + end + + def on_path(node) + test, children = *node + + current = process(test) + + if current + @cursor = current + current = process(children) + end + + return current + end + + def on_test(node) + nodes = [] + ns, name = *node + + @cursor.children.each do |child| + if child.is_a?(XML::Element) and child.name == name and child.namespace == ns + nodes << child + end + end + + return nodes + end + end # Evaluator + end # XPath +end # Oga