Support for the XPath substring() function.

This commit is contained in:
Yorick Peterse 2014-08-25 23:13:34 +02:00
parent 5382891106
commit a1a2190fe2
2 changed files with 69 additions and 0 deletions

View File

@ -920,6 +920,45 @@ module Oga
return sep.empty? ? sep : after
end
##
# Processes the `substring()` function call.
#
# This function call returns the substring of the 1st argument, starting
# at the position given in the 2nd argument. If the third argument is
# given it is used as the length for the substring, otherwise the string
# is consumed until the end.
#
# XPath string indexes start from position 1, not position 0.
#
# @example Using a literal string
# substring("foo", 2) # => "oo"
#
# @exxample Using a literal string with a custom length
# substring("foo", 1, 2) # => "fo"
#
# @example Using a node set
# substring(users/user/username, 5)
#
# @param [Oga::XML::NodeSet] context
# @param [Oga::XPath::Node] haystack
# @param [Oga::XPath::Node] start
# @param [Oga::XPath::Node] length
# @return [String]
#
def on_call_substring(context, haystack, start, length = nil)
haystack_str = on_call_string(context, haystack)
start_index = on_call_number(context, start).to_i - 1
if length
length_int = on_call_number(context, length).to_i - 1
stop_index = start_index + length_int
else
stop_index = -1
end
return haystack_str[start_index..stop_index]
end
##
# Processes an `(int)` node.
#

View File

@ -0,0 +1,30 @@
require 'spec_helper'
describe Oga::XPath::Evaluator do
context 'substring() function' do
before do
@document = parse('<root><a>foobar</a><b>3</b></root>')
@evaluator = described_class.new(@document)
end
example 'return the substring of a string' do
@evaluator.evaluate('substring("foo", 2)').should == 'oo'
end
example 'return the substring of a string using a custom length' do
@evaluator.evaluate('substring("foo", 2, 1)').should == 'o'
end
example 'return the substring of a node set' do
@evaluator.evaluate('substring(root/a, 2)').should == 'oobar'
end
example 'return the substring of a node set with a node set as the length' do
@evaluator.evaluate('substring(root/a, 1, root/b)').should == 'foo'
end
example 'return an empty string when the source string is empty' do
@evaluator.evaluate('substring("", 1, 3)').should == ''
end
end
end