diff --git a/lib/rexml/functions.rb b/lib/rexml/functions.rb
index 8881c3fa..281d3809 100644
--- a/lib/rexml/functions.rb
+++ b/lib/rexml/functions.rb
@@ -22,8 +22,10 @@ def initialize
:variables,
:variables=,
:context=,
- :get_namespace,
+ :target_named_node,
:send,
+ :compare_language,
+ :string_value,
]
class << self
def method_added(name)
@@ -60,41 +62,27 @@ def id( object )
end
def local_name(node_set=nil)
- get_namespace(node_set) do |node|
- return node.local_name
- end
- ""
+ target_named_node(node_set)&.local_name || ""
end
def namespace_uri( node_set=nil )
- get_namespace( node_set ) do |node|
- return node.namespace
- end
- ""
+ target_named_node(node_set)&.namespace || ""
end
def name( node_set=nil )
- get_namespace( node_set ) do |node|
- return node.expanded_name
- end
- ""
+ target_named_node(node_set)&.expanded_name || ""
end
# Helper method.
- def get_namespace( node_set = nil )
- if node_set == nil
- yield @context[:node] if @context[:node].respond_to?(:namespace)
- else
- if node_set.kind_of? Array
- result = []
- XPathParser.sort(node_set).each do |node|
- result << yield(node) if node.respond_to?(:namespace)
- end
- result
- elsif node_set.respond_to? :namespace
- yield node_set
+ def target_named_node(node_set = nil)
+ node =
+ case node_set
+ when nil
+ node = @context[:node]
+ when Array
+ node = XPathParser.sort(node_set).first
end
- end
+ node if node.respond_to?(:namespace)
end
# A node-set is converted to a string by returning the string-value of the
diff --git a/test/functions/test_base.rb b/test/functions/test_base.rb
index eb67fa3f..36f2ea16 100644
--- a/test/functions/test_base.rb
+++ b/test/functions/test_base.rb
@@ -13,6 +13,16 @@ def setup
REXML::Functions.context = nil
end
+ def test_available_functions
+ expected_functions = %w[
+ boolean ceiling concat contains count false floor id lang last local-name
+ name namespace-uri normalize-space not number position round starts-with
+ string string-length substring substring-after substring-before sum translate true
+ ]
+ methods = REXML::FunctionsClass.class_variable_get(:@@available_functions).keys.sort
+ assert_equal expected_functions, methods.map { |m| m.to_s.tr('_', '-') }.sort
+ end
+
def test_functions
# trivial text() test
# confuse-a-function
diff --git a/test/functions/test_local_name.rb b/test/functions/test_local_name.rb
index 97c9e748..01c09eed 100644
--- a/test/functions/test_local_name.rb
+++ b/test/functions/test_local_name.rb
@@ -16,7 +16,7 @@ def test_one
XML
- node_set = document.root.children
+ node_set = document.root.elements.to_a
assert_equal("child", REXML::Functions.local_name(node_set))
end
@@ -27,7 +27,7 @@ def test_multiple
XML
- node_set = document.root.children
+ node_set = document.root.elements.to_a
assert_equal("child1", REXML::Functions.local_name(node_set))
end
@@ -35,6 +35,20 @@ def test_nonexistent
assert_equal("", REXML::Functions.local_name([]))
end
+ def test_attribute
+ document = REXML::Document.new("")
+ node_set = [document.root.attributes.to_a.last]
+ assert_equal("attr", REXML::Functions.local_name(node_set))
+ end
+
+ def test_non_named
+ document = REXML::Document.new("text")
+ children = document.root.children
+ assert_equal("", REXML::Functions.local_name([children[0]]))
+ assert_equal("", REXML::Functions.local_name([children[1]]))
+ assert_equal("", REXML::Functions.local_name(children))
+ end
+
def test_context
document = REXML::Document.new("")
REXML::Functions.context = {node: document.root}