diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index d906ae5..4ca6b58 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -1132,6 +1132,36 @@ module Oga return false end + ## + # Processes the `sum()` function call. + # + # This function call takes a node set, converts each node to a number and + # then sums the values. + # + # As an example, take the following XML: + # + # + # 1 + # 2 + # + # + # Using the expression `sum(root/*)` the return value would be `3.0`. + # + # @param [Oga::XML::NodeSet] context + # @param [Oga::XPath::Node] expression + # @return [Float] + # + def on_call_sum(context, expression) + nodes = process(expression, context) + sum = 0.0 + + nodes.each do |node| + sum += node.text.to_f + end + + return sum + end + ## # Processes an `(int)` node. # diff --git a/spec/oga/xpath/evaluator/calls/sum_spec.rb b/spec/oga/xpath/evaluator/calls/sum_spec.rb new file mode 100644 index 0000000..dadaf43 --- /dev/null +++ b/spec/oga/xpath/evaluator/calls/sum_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe Oga::XPath::Evaluator do + context 'sum() spec' do + before do + @document = parse('12') + @evaluator = described_class.new(@document) + end + + example 'return the sum of the node' do + # The test of is "12", which is then converted to a number. + @evaluator.evaluate('sum(root)').should == 12.0 + end + + example 'return the sum of the child nodes of the node' do + @evaluator.evaluate('sum(root/*)').should == 3.0 + end + end +end