From 616fd42600aecdde33d3ca0d47ecfeeb96d7802c Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Sun, 19 Jul 2015 00:11:58 +0200 Subject: [PATCH] XPath compiler support for the "attribute" axis --- lib/oga/xpath/compiler.rb | 50 +++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/lib/oga/xpath/compiler.rb b/lib/oga/xpath/compiler.rb index 6f65c8c..b6c208c 100644 --- a/lib/oga/xpath/compiler.rb +++ b/lib/oga/xpath/compiler.rb @@ -166,11 +166,20 @@ module Oga # @return [Oga::Ruby::Node] # def on_axis_attribute(ast, input) - ns, name = *ast + input.is_a?(XML::Element).if_true do + attribute = literal('attribute') - query = ns ? "#{ns}:#{name}" : name + input.attributes.each.add_block(attribute) do + name_match = match_name_and_namespace(ast, attribute) - input.get(string(query)) + if name_match + name_match.if_true { yield attribute } + else + yield attribute + end + end + end + #input.attribute(string(query)) end ## @@ -294,19 +303,10 @@ module Oga # @return [Oga::Ruby::Node] # def on_test(ast, input) - ns, name = *ast + condition = element_or_attribute(input) + name_match = match_name_and_namespace(ast, input) - condition = element_or_attribute(input) - - if name != STAR - condition = condition.and(input.name.eq(string(name))) - end - - if ns and ns != STAR - condition = condition.and(input.namespace_name.eq(string(ns))) - end - - condition + name_match ? condition.and(name_match) : condition end ## @@ -403,6 +403,26 @@ module Oga node.is_a?(XML::Attribute).or(node.is_a?(XML::Element)) end + # @param [AST::Node] ast + # @param [Oga::Ruby::Node] input + # @return [Oga::Ruby::Node] + def match_name_and_namespace(ast, input) + ns, name = *ast + + condition = nil + + if name != STAR + condition = input.name.eq(string(name)) + end + + if ns and ns != STAR + ns_match = input.namespace_name.eq(string(ns)) + condition = condition ? condition.and(ns_match) : ns_match + end + + condition + end + # @return [Oga::Ruby::Node] def matched_literal literal('matched')