From 7512a57adafb441c2e949198655f0d1154f6b3a1 Mon Sep 17 00:00:00 2001 From: Joseph Walton Date: Wed, 17 Dec 2014 17:39:28 +1100 Subject: [PATCH 1/4] SI-9047: Add unit tests for the working and non-working cases. --- src/test/scala/scala/xml/XMLTest.scala | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/scala/scala/xml/XMLTest.scala b/src/test/scala/scala/xml/XMLTest.scala index 01431baf1..0c0b4e4b3 100644 --- a/src/test/scala/scala/xml/XMLTest.scala +++ b/src/test/scala/scala/xml/XMLTest.scala @@ -836,4 +836,21 @@ expected closing tag of foo assertEquals("""""", pp.format(x)) } + @UnitTest + def issueSI9047AttributeFromSingleChildElementWorks: Unit = { + val x = + + val b = x \ "a" \ "@b" + + assertEquals(List("1"), b map (_.text)) + } + + @UnitTest + def issueSI9047AttributeMultipleChildElementsWorks: Unit = { + val x = + + val b = x \ "a" \ "@b" + + assertEquals(List("1", "2"), b map (_.text)) + } } From 444fcaece0007a63494d0f6c411a739792a03f10 Mon Sep 17 00:00:00 2001 From: Joseph Walton Date: Wed, 17 Dec 2014 18:20:54 +1100 Subject: [PATCH 2/4] SI-9047: Extract attributes from NodeSeqs with more than one element. Allow querying for attributes when a NodeSeq has more than one element. --- src/main/scala/scala/xml/NodeSeq.scala | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main/scala/scala/xml/NodeSeq.scala b/src/main/scala/scala/xml/NodeSeq.scala index 5f2b6b6c9..f2268bcd4 100644 --- a/src/main/scala/scala/xml/NodeSeq.scala +++ b/src/main/scala/scala/xml/NodeSeq.scala @@ -96,8 +96,7 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S def \(that: String): NodeSeq = { def fail = throw new IllegalArgumentException(that) def atResult = { - lazy val y = this(0) - val attr = + this flatMap (y => { if (that.length == 1) fail else if (that(1) == '{') { val i = that indexOf '}' @@ -106,12 +105,8 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S if (uri == "" || key == "") fail else y.attribute(uri, key) } else y.attribute(that drop 1) - - attr match { - case Some(x) => Group(x) - case _ => NodeSeq.Empty - } - } + }) + }.flatten def makeSeq(cond: (Node) => Boolean) = NodeSeq fromSeq (this flatMap (_.child) filter cond) @@ -119,7 +114,7 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S that match { case "" => fail case "_" => makeSeq(!_.isAtom) - case _ if (that(0) == '@' && this.length == 1) => atResult + case _ if that(0) == '@' => atResult case _ => makeSeq(_.label == that) } } From fc27be1061bdc57d4de03a93310074826e21f66b Mon Sep 17 00:00:00 2001 From: Joseph Walton Date: Thu, 18 Dec 2014 18:45:01 +1100 Subject: [PATCH 3/4] SI-9047: Remove redundant braces. --- src/main/scala/scala/xml/NodeSeq.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/scala/xml/NodeSeq.scala b/src/main/scala/scala/xml/NodeSeq.scala index f2268bcd4..f63b36b14 100644 --- a/src/main/scala/scala/xml/NodeSeq.scala +++ b/src/main/scala/scala/xml/NodeSeq.scala @@ -96,7 +96,7 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S def \(that: String): NodeSeq = { def fail = throw new IllegalArgumentException(that) def atResult = { - this flatMap (y => { + this flatMap (y => if (that.length == 1) fail else if (that(1) == '{') { val i = that indexOf '}' @@ -105,7 +105,7 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S if (uri == "" || key == "") fail else y.attribute(uri, key) } else y.attribute(that drop 1) - }) + ) }.flatten def makeSeq(cond: (Node) => Boolean) = From 9aabe50ee0d6a093ffa1417e8b9cc02b8c70586a Mon Sep 17 00:00:00 2001 From: Joseph Walton Date: Fri, 9 Jun 2017 14:17:23 +1000 Subject: [PATCH 4/4] SI-9047: Ensure Group is returned, and adjust added tests. Ensure that Group is returned, rather than NodeSeq, and adjust the newer test now that multiple attributes are successfully returned. --- shared/src/main/scala/scala/xml/NodeSeq.scala | 9 ++++++--- shared/src/test/scala/scala/xml/AttributeTest.scala | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/shared/src/main/scala/scala/xml/NodeSeq.scala b/shared/src/main/scala/scala/xml/NodeSeq.scala index 2aa88e4ce..df43f2553 100644 --- a/shared/src/main/scala/scala/xml/NodeSeq.scala +++ b/shared/src/main/scala/scala/xml/NodeSeq.scala @@ -95,7 +95,7 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S def \(that: String): NodeSeq = { def fail = throw new IllegalArgumentException(that) def atResult = { - this flatMap (y => + this flatMap (y => ( if (that.length == 1) fail else if (that(1) == '{') { val i = that indexOf '}' @@ -104,8 +104,11 @@ abstract class NodeSeq extends AbstractSeq[Node] with immutable.Seq[Node] with S if (uri == "" || key == "") fail else y.attribute(uri, key) } else y.attribute(that drop 1) - ) - }.flatten + ).getOrElse(Nil)) match { + case NodeSeq.Empty => NodeSeq.Empty + case x => Group(x) + } + } def makeSeq(cond: (Node) => Boolean) = NodeSeq fromSeq (this flatMap (_.child) filter cond) diff --git a/shared/src/test/scala/scala/xml/AttributeTest.scala b/shared/src/test/scala/scala/xml/AttributeTest.scala index 8943a0a00..b7a0d3115 100644 --- a/shared/src/test/scala/scala/xml/AttributeTest.scala +++ b/shared/src/test/scala/scala/xml/AttributeTest.scala @@ -147,9 +147,9 @@ class AttributeTest { val b = xml \ "b" assertEquals(2, b.length) assertEquals(NodeSeq.fromSeq(Seq(, )), b) - val barFail = b \ "@bar" + val barAttributesDirect = b \ "@bar" val barList = b.map(_ \ "@bar") - assertEquals(NodeSeq.Empty, barFail) + assertEquals(Group(Seq(Text("1"), Text("2"))), barAttributesDirect) assertEquals(List(Group(Seq(Text("1"))), Group(Seq(Text("2")))), barList) }