Skip to content

Commit 2017fa3

Browse files
authored
Merge pull request #172 from ashawley/fix-attribute-order
XML attributes parsed in reverse order
2 parents a359485 + eaf1532 commit 2017fa3

File tree

8 files changed

+68
-2
lines changed

8 files changed

+68
-2
lines changed

Diff for: jvm/src/test/scala/scala/xml/AttributeTest.scala

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package scala.xml
2+
3+
import org.junit.Test
4+
import org.junit.Assert.assertEquals
5+
import org.junit.Assert.assertNotEquals
6+
7+
class AttributeTestJVM {
8+
9+
@Test
10+
def attributeOrder: Unit = {
11+
val x = <x y="1" z="2"/>
12+
assertEquals("""<x y="1" z="2"/>""", x.toString)
13+
}
14+
15+
@Test
16+
def attributesFromString: Unit = {
17+
val str = """<x y="1" z="2"/>"""
18+
val doc = XML.loadString(str)
19+
assertEquals(str, doc.toString)
20+
}
21+
22+
@Test
23+
def attributesAndNamespaceFromString: Unit = {
24+
val str = """<x xmlns:w="w" y="1" z="2"/>"""
25+
val doc = XML.loadString(str)
26+
assertNotEquals(str, doc.toString)
27+
val str2 = """<x y="1" z="2" xmlns:w="w"/>"""
28+
val doc2 = XML.loadString(str2)
29+
assertEquals(str2, doc2.toString)
30+
}
31+
32+
@Test(expected=classOf[SAXParseException])
33+
def attributesFromStringWithDuplicate: Unit = {
34+
val str = """<elem one="test" one="test1" two="test2" three="test3"></elem>"""
35+
XML.loadString(str)
36+
}
37+
}

Diff for: jvm/src/test/scala/scala/xml/parsing/ConstructingParserTest.scala

+10
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,14 @@ class ConstructingParserTest {
7171

7272
ConstructingParser.fromSource(source, true).content(TopScope)
7373
}
74+
75+
@Test
76+
def SI6341issue65: Unit = {
77+
val str = """<elem one="test" two="test2" three="test3"/>"""
78+
val cpa = ConstructingParser.fromSource(io.Source.fromString(str), preserveWS = true)
79+
val cpadoc = cpa.document()
80+
val ppr = new PrettyPrinter(80,5)
81+
val out = ppr.format(cpadoc.docElem)
82+
assertEquals(str, out)
83+
}
7484
}

Diff for: shared/src/main/scala/scala/xml/MetaData.scala

+5
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ abstract class MetaData
155155
if (f(this)) copy(next filter f)
156156
else next filter f
157157

158+
def reverse: MetaData =
159+
foldLeft(Null: MetaData) { (x, xs) =>
160+
xs.copy(x)
161+
}
162+
158163
/** returns key of this MetaData item */
159164
def key: String
160165

Diff for: shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ abstract class FactoryAdapter extends DefaultHandler with factory.XMLLoader[Node
158158
if (scopeStack.isEmpty) TopScope
159159
else scopeStack.head
160160

161-
for (i <- 0 until attributes.getLength()) {
161+
for (i <- (0 until attributes.getLength).reverse) {
162162
val qname = attributes getQName i
163163
val value = attributes getValue i
164164
val (pre, key) = splitName(qname)

Diff for: shared/src/main/scala/scala/xml/parsing/MarkupParser.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ trait MarkupParser extends MarkupParserCommon with TokenTests {
339339
if (!aMap.wellformed(scope))
340340
reportSyntaxError("double attribute")
341341

342-
(aMap, scope)
342+
(aMap.reverse, scope)
343343
}
344344

345345
/**

Diff for: shared/src/test/scala/scala/xml/AttributeTest.scala

+5
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ class AttributeTest {
4949
}
5050

5151
@Test
52+
def attributeOrder: Unit = {
53+
val x = <x y="1" z="2"/>
54+
assertEquals("""<x y="1" z="2"/>""", x.toString)
55+
}
56+
5257
def attributeToString: Unit = {
5358
val expected: String = """<b x="&amp;"/>"""
5459
assertEquals(expected, (<b x="&amp;"/>).toString)

Diff for: shared/src/test/scala/scala/xml/MetaDataTest.scala

+7
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,11 @@ class MetaDataTest {
5454
assertEquals(new Atom(3), domatch(z2))
5555
}
5656

57+
@Test
58+
def reverseTest: Unit = {
59+
assertEquals("", Null.reverse.toString)
60+
assertEquals(""" b="c"""", <a b="c"/>.attributes.reverse.toString)
61+
assertEquals(""" d="e" b="c"""", <a b="c" d="e"/>.attributes.reverse.toString)
62+
}
63+
5764
}

Diff for: shared/src/test/scala/scala/xml/UtilityTest.scala

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class UtilityTest {
3838

3939
@Test
4040
def sort: Unit = {
41+
assertEquals("", xml.Utility.sort(<a/>.attributes).toString)
42+
assertEquals(""" b="c"""", xml.Utility.sort(<a b="c"/>.attributes).toString)
4143
val q = xml.Utility.sort(<a g='3' j='2' oo='2' a='2'/>)
4244
assertEquals(" a=\"2\" g=\"3\" j=\"2\" oo=\"2\"", xml.Utility.sort(q.attributes).toString)
4345
val pp = new xml.PrettyPrinter(80,5)

0 commit comments

Comments
 (0)