Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 14 additions & 26 deletions lib/rexml/functions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Comment on lines +80 to 84
end
node if node.respond_to?(:namespace)
end

# A node-set is converted to a string by returning the string-value of the
Expand Down
10 changes: 10 additions & 0 deletions test/functions/test_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 16 additions & 2 deletions test/functions/test_local_name.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_one
<x:child/>
</root>
XML
node_set = document.root.children
node_set = document.root.elements.to_a
assert_equal("child", REXML::Functions.local_name(node_set))
end

Expand All @@ -27,14 +27,28 @@ def test_multiple
<x:child2/>
</root>
XML
node_set = document.root.children
node_set = document.root.elements.to_a
assert_equal("child1", REXML::Functions.local_name(node_set))
end

def test_nonexistent
assert_equal("", REXML::Functions.local_name([]))
end

def test_attribute
document = REXML::Document.new("<root xmlns:x='http://example.com/x/' x:attr='value' />")
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("<root>text<!-- comment --><a/></root>")
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("<root/>")
REXML::Functions.context = {node: document.root}
Expand Down
Loading