Skip to content

Commit ea2bf33

Browse files
committed
Sort nodeset on demand
1 parent a6aa43c commit ea2bf33

3 files changed

Lines changed: 14 additions & 7 deletions

File tree

lib/rexml/functions.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def get_namespace( node_set = nil )
8787
else
8888
if node_set.respond_to? :each
8989
result = []
90-
node_set.each do |node|
90+
XPathParser.sort(node_set.to_a).each do |node|
9191
result << yield(node) if node.respond_to?(:namespace)
9292
end
9393
result
@@ -149,7 +149,7 @@ def string( object=@context[:node] )
149149
else
150150
case object
151151
when Array
152-
string(object[0])
152+
string(XPathParser.sort(object)[0])
153153
when Float
154154
if object.nan?
155155
"NaN"

lib/rexml/xpath_parser.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def match(path_stack, node)
156156
result = expr(path_stack, nodeset)
157157
case result
158158
when Array # nodeset
159-
result.uniq
159+
XPathParser.sort(result)
160160
else
161161
[result]
162162
end
@@ -199,7 +199,7 @@ def expr( path_stack, nodeset, context=nil )
199199
nodeset = [nodeset.first.root_node]
200200
when :self
201201
nodeset = step(path_stack) do
202-
[:iterate_nodesets, [nodeset]]
202+
[:iterate_nodesets, [XPathParser.sort(nodeset)]]
203203
end
204204
when :child
205205
nodeset = step(path_stack) do
@@ -323,7 +323,7 @@ def expr( path_stack, nodeset, context=nil )
323323
# If result is a nodeset, apply following predicates
324324
path_stack.unshift(:node)
325325
nodeset = step(path_stack) do
326-
[:iterate_nodesets, [result]]
326+
[:iterate_nodesets, [XPathParser.sort(result)]]
327327
end
328328
else
329329
return result
@@ -621,7 +621,7 @@ def step(path_stack, any_type: :element)
621621
nodes << node
622622
end
623623
end
624-
new_nodeset = sort(nodes.to_a)
624+
new_nodeset = nodes.to_a
625625
ensure
626626
leave(:step, path_stack, new_nodeset) if @debug
627627
end
@@ -761,7 +761,7 @@ def leave(tag, *args)
761761
# in and out of function calls. If I knew what the index of the nodes was,
762762
# I wouldn't have to do this. Maybe add a document IDX for each node?
763763
# Problems with mutable documents. Or, rewrite everything.
764-
def sort(array_of_nodes)
764+
def self.sort(array_of_nodes)
765765
return array_of_nodes if array_of_nodes.size <= 1
766766

767767
new_arry = []

test/test_jaxen.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ def process_value_of(context, variables, namespaces, value_of)
8787
xpath = value_of.attributes["select"]
8888
matched = XPath.match(context, xpath, namespaces, variables, strict: true)
8989

90+
# XPath.match can be a nodeset or a primitive value wrapped in an array.
91+
# We need to unwrap primitive value because Functions doesn't accept array which is not a nodeset.
92+
unless matched.all? { |node| node.is_a?(REXML::Node) }
93+
raise "[BUG] Primitive value should be a single value: #{matched.inspect}" if matched.size != 1
94+
matched = matched.first
95+
end
96+
9097
message = user_message(context, xpath, matched)
9198
assert_equal(expected || "",
9299
REXML::Functions.string(matched),

0 commit comments

Comments
 (0)