diff --git a/lib/rexml/xpath_parser.rb b/lib/rexml/xpath_parser.rb
index f86a87e6..cde2e5d5 100644
--- a/lib/rexml/xpath_parser.rb
+++ b/lib/rexml/xpath_parser.rb
@@ -144,7 +144,7 @@ def match(path_stack, nodeset)
result = expr(path_stack, nodeset)
case result
when Array # nodeset
- unnode(result)
+ unnode(result).uniq
else
[result]
end
diff --git a/test/xpath/test_base.rb b/test/xpath/test_base.rb
index 53264a9e..b923eed2 100644
--- a/test/xpath/test_base.rb
+++ b/test/xpath/test_base.rb
@@ -416,12 +416,103 @@ 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()")
+ def test_preceding_multiple
+ source = <<-XML
+
+
+
+ XML
+ doc = REXML::Document.new(source)
+ matches = REXML::XPath.match(doc, "a/d/preceding::*")
+ assert_equal(["d", "c", "b"], matches.map(&:name))
+ end
+
+ def test_following_multiple
+ source = <<-XML
+
+
+
+ XML
+ doc = REXML::Document.new(source)
+ matches = REXML::XPath.match(doc, "a/d/following::*")
+ assert_equal(["d", "e", "f"], matches.map(&:name))
+ end
+
+ def test_following_sibling_across_multiple_nodes
+ source = <<-XML
+
+
+
+
+
+
+
+
+ XML
+ doc = REXML::Document.new(source)
+ matches = REXML::XPath.match(doc, "a/b/x/following-sibling::*")
+ assert_equal(["c", "d", "e"], matches.map(&:name))
+ end
+
+ def test_following_sibling_within_single_node
+ source = <<-XML
+
+
+
+
+
+ XML
+ doc = REXML::Document.new(source)
+ matches = REXML::XPath.match(doc, "a/b/x/following-sibling::*")
+ assert_equal(["c", "d", "x", "e"], matches.map(&:name))
+ end
+
+ def test_following_sibling_predicates
+ source = <<-XML
+
+ XML
+ doc = REXML::Document.new(source)
+ # Finds a node flowing
+ matches = REXML::XPath.match(doc, "//a/following-sibling::*[1]")
+ assert_equal(["w", "x", "y", "z"], matches.map(&:name))
+ end
+
+ def test_preceding_sibling_across_multiple_nodes
+ source = <<-XML
+
+
+
+
+
+
+
+
+ XML
+ doc = REXML::Document.new(source)
+ matches = REXML::XPath.match(doc, "a/b/x/preceding-sibling::*")
assert_equal(["e", "d", "c"], matches.map(&:name))
end
+ def test_preceding_sibling_within_single_node
+ source = <<-XML
+
+
+
+
+
+ XML
+ doc = REXML::Document.new(source)
+ matches = REXML::XPath.match(doc, "a/b/x/preceding-sibling::*")
+ assert_equal(["e", "x", "d", "c"], matches.map(&:name))
+ end
+
def test_following
d = Document.new ""
start = XPath.first( d, "/a/b[@id='0']" )