From cb0c9d280da128463a65692e87ba24e3a6682d34 Mon Sep 17 00:00:00 2001 From: tompng Date: Thu, 1 May 2025 03:04:48 +0900 Subject: [PATCH 1/2] Fix reverse sort in xpath_parser --- lib/rexml/xpath_parser.rb | 2 +- test/xpath/test_base.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/rexml/xpath_parser.rb b/lib/rexml/xpath_parser.rb index 5eb1e5a9..f86a87e6 100644 --- a/lib/rexml/xpath_parser.rb +++ b/lib/rexml/xpath_parser.rb @@ -671,7 +671,7 @@ def sort(array_of_nodes, order) if order == :forward index else - -index + index.map(&:-@) end end ordered.collect do |_index, node| diff --git a/test/xpath/test_base.rb b/test/xpath/test_base.rb index 1dacd69d..d5fa7768 100644 --- a/test/xpath/test_base.rb +++ b/test/xpath/test_base.rb @@ -409,6 +409,10 @@ def test_preceding assert_equal("c", matches[0].name) assert_equal("b", matches[1].name) + d = REXML::Document.new("") + cs = REXML::XPath.match(d, "a/d/preceding::node()") + assert_equal(["d", "c", "c", "b", "b"], cs.map(&:name)) + s = "" d = REXML::Document.new(s) c = REXML::XPath.match( d, "//c[@id = '5']") From d5f5f835e39b1dceb91ae5ac4c6f664f41cf85ce Mon Sep 17 00:00:00 2001 From: tompng Date: Fri, 2 May 2025 04:51:22 +0900 Subject: [PATCH 2/2] Test xpathparser sort with preceding-sibling --- test/xpath/test_base.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/xpath/test_base.rb b/test/xpath/test_base.rb index d5fa7768..53264a9e 100644 --- a/test/xpath/test_base.rb +++ b/test/xpath/test_base.rb @@ -409,10 +409,6 @@ def test_preceding assert_equal("c", matches[0].name) assert_equal("b", matches[1].name) - d = REXML::Document.new("") - cs = REXML::XPath.match(d, "a/d/preceding::node()") - assert_equal(["d", "c", "c", "b", "b"], cs.map(&:name)) - s = "" d = REXML::Document.new(s) c = REXML::XPath.match( d, "//c[@id = '5']") @@ -420,6 +416,12 @@ def test_preceding assert_equal( 4, cs.length ) end + def test_preceding_sibling + d = REXML::Document.new("") + matches = REXML::XPath.match(d, "a/b/x/preceding-sibling::node()") + assert_equal(["e", "d", "c"], matches.map(&:name)) + end + def test_following d = Document.new "" start = XPath.first( d, "/a/b[@id='0']" )