diff --git a/jvm/src/test/scala/scala/xml/AttributeTest.scala b/jvm/src/test/scala/scala/xml/AttributeTest.scala new file mode 100644 index 000000000..11511d1d0 --- /dev/null +++ b/jvm/src/test/scala/scala/xml/AttributeTest.scala @@ -0,0 +1,37 @@ +package scala.xml + +import org.junit.Test +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotEquals + +class AttributeTestJVM { + + @Test + def attributeOrder: Unit = { + val x = + assertEquals("""""", x.toString) + } + + @Test + def attributesFromString: Unit = { + val str = """""" + val doc = XML.loadString(str) + assertEquals(str, doc.toString) + } + + @Test + def attributesAndNamespaceFromString: Unit = { + val str = """""" + val doc = XML.loadString(str) + assertNotEquals(str, doc.toString) + val str2 = """""" + val doc2 = XML.loadString(str2) + assertEquals(str2, doc2.toString) + } + + @Test(expected=classOf[SAXParseException]) + def attributesFromStringWithDuplicate: Unit = { + val str = """""" + XML.loadString(str) + } +} diff --git a/jvm/src/test/scala/scala/xml/parsing/ConstructingParserTest.scala b/jvm/src/test/scala/scala/xml/parsing/ConstructingParserTest.scala index 4a8cf3134..7dfa33b6b 100644 --- a/jvm/src/test/scala/scala/xml/parsing/ConstructingParserTest.scala +++ b/jvm/src/test/scala/scala/xml/parsing/ConstructingParserTest.scala @@ -71,4 +71,14 @@ class ConstructingParserTest { ConstructingParser.fromSource(source, true).content(TopScope) } + + @Test + def SI6341issue65: Unit = { + val str = """""" + val cpa = ConstructingParser.fromSource(io.Source.fromString(str), preserveWS = true) + val cpadoc = cpa.document() + val ppr = new PrettyPrinter(80,5) + val out = ppr.format(cpadoc.docElem) + assertEquals(str, out) + } } diff --git a/shared/src/main/scala/scala/xml/MetaData.scala b/shared/src/main/scala/scala/xml/MetaData.scala index ee6824b03..a856c5c39 100644 --- a/shared/src/main/scala/scala/xml/MetaData.scala +++ b/shared/src/main/scala/scala/xml/MetaData.scala @@ -155,6 +155,11 @@ abstract class MetaData if (f(this)) copy(next filter f) else next filter f + def reverse: MetaData = + foldLeft(Null: MetaData) { (x, xs) => + xs.copy(x) + } + /** returns key of this MetaData item */ def key: String diff --git a/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala b/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala index 11db0ac61..1c46d7283 100644 --- a/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala +++ b/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala @@ -158,7 +158,7 @@ abstract class FactoryAdapter extends DefaultHandler with factory.XMLLoader[Node if (scopeStack.isEmpty) TopScope else scopeStack.head - for (i <- 0 until attributes.getLength()) { + for (i <- (0 until attributes.getLength).reverse) { val qname = attributes getQName i val value = attributes getValue i val (pre, key) = splitName(qname) diff --git a/shared/src/main/scala/scala/xml/parsing/MarkupParser.scala b/shared/src/main/scala/scala/xml/parsing/MarkupParser.scala index 3ddc626b2..33717ce71 100755 --- a/shared/src/main/scala/scala/xml/parsing/MarkupParser.scala +++ b/shared/src/main/scala/scala/xml/parsing/MarkupParser.scala @@ -339,7 +339,7 @@ trait MarkupParser extends MarkupParserCommon with TokenTests { if (!aMap.wellformed(scope)) reportSyntaxError("double attribute") - (aMap, scope) + (aMap.reverse, scope) } /** diff --git a/shared/src/test/scala/scala/xml/AttributeTest.scala b/shared/src/test/scala/scala/xml/AttributeTest.scala index 285d24795..159946231 100644 --- a/shared/src/test/scala/scala/xml/AttributeTest.scala +++ b/shared/src/test/scala/scala/xml/AttributeTest.scala @@ -49,6 +49,11 @@ class AttributeTest { } @Test + def attributeOrder: Unit = { + val x = + assertEquals("""""", x.toString) + } + def attributeToString: Unit = { val expected: String = """""" assertEquals(expected, ().toString) diff --git a/shared/src/test/scala/scala/xml/MetaDataTest.scala b/shared/src/test/scala/scala/xml/MetaDataTest.scala index 87be69b82..d6bacc0ef 100644 --- a/shared/src/test/scala/scala/xml/MetaDataTest.scala +++ b/shared/src/test/scala/scala/xml/MetaDataTest.scala @@ -54,4 +54,11 @@ class MetaDataTest { assertEquals(new Atom(3), domatch(z2)) } + @Test + def reverseTest: Unit = { + assertEquals("", Null.reverse.toString) + assertEquals(""" b="c"""", .attributes.reverse.toString) + assertEquals(""" d="e" b="c"""", .attributes.reverse.toString) + } + } diff --git a/shared/src/test/scala/scala/xml/UtilityTest.scala b/shared/src/test/scala/scala/xml/UtilityTest.scala index a27fb0b1a..765b9bad8 100644 --- a/shared/src/test/scala/scala/xml/UtilityTest.scala +++ b/shared/src/test/scala/scala/xml/UtilityTest.scala @@ -38,6 +38,8 @@ class UtilityTest { @Test def sort: Unit = { + assertEquals("", xml.Utility.sort(.attributes).toString) + assertEquals(""" b="c"""", xml.Utility.sort(.attributes).toString) val q = xml.Utility.sort() assertEquals(" a=\"2\" g=\"3\" j=\"2\" oo=\"2\"", xml.Utility.sort(q.attributes).toString) val pp = new xml.PrettyPrinter(80,5)