Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Xml attribute fixes #87

Merged
merged 2 commits into from

2 participants

@khernyo
  • Fixed equality and string representation of xml attributes with null value
  • Accept prefixed xml attributes with null value

More details can be found in the commit messages.

khernyo added some commits
@khernyo khernyo Fixed equality and string representation of xml attributes with null …
…value

Prior to this patch <t a={ null: String }/> was not equal to <t/> and
it's string representation was "<t ></t>" instead of "<t></t>"

This includes changing MetaData.normalize() so that it doesn't reverse
the chain. On the downside, the iterate function in MetaData.normalize()
is not tail-recursive now.
4787f88
@khernyo khernyo Accept prefixed xml attributes with null value
This changes makes PrefixedAttribute work the same way as
UnprefixedAttribute with respect to null values:

<t p:a={ null: String }/> is accepted and results in <t/>
51089b3
@paulp paulp merged commit 51089b3 into scala:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 7, 2012
  1. @khernyo

    Fixed equality and string representation of xml attributes with null …

    khernyo authored
    …value
    
    Prior to this patch <t a={ null: String }/> was not equal to <t/> and
    it's string representation was "<t ></t>" instead of "<t></t>"
    
    This includes changing MetaData.normalize() so that it doesn't reverse
    the chain. On the downside, the iterate function in MetaData.normalize()
    is not tail-recursive now.
  2. @khernyo

    Accept prefixed xml attributes with null value

    khernyo authored
    This changes makes PrefixedAttribute work the same way as
    UnprefixedAttribute with respect to null values:
    
    <t p:a={ null: String }/> is accepted and results in <t/>
This page is out of date. Refresh to see the latest.
View
4 src/library/scala/xml/Elem.scala
@@ -41,7 +41,7 @@ object Elem {
class Elem(
override val prefix: String,
val label: String,
- override val attributes: MetaData,
+ attributes1: MetaData,
override val scope: NamespaceBinding,
val child: Node*)
extends Node with Serializable
@@ -49,6 +49,8 @@ extends Node with Serializable
final override def doCollectNamespaces = true
final override def doTransform = true
+ override val attributes = MetaData.normalize(attributes1, scope)
+
if (prefix == "")
throw new IllegalArgumentException("prefix of zero length, use null instead")
View
4 src/library/scala/xml/MetaData.scala
@@ -38,8 +38,8 @@ object MetaData {
def iterate(md: MetaData, normalized_attribs: MetaData, set: Set[String]): MetaData = {
lazy val key = getUniversalKey(md, scope)
if (md eq Null) normalized_attribs
- else if (set(key)) iterate(md.next, normalized_attribs, set)
- else iterate(md.next, md copy normalized_attribs, set + key)
+ else if ((md.value eq null) || set(key)) iterate(md.next, normalized_attribs, set)
+ else md copy iterate(md.next, normalized_attribs, set + key)
}
iterate(attribs, Null, Set())
}
View
15 src/library/scala/xml/PrefixedAttribute.scala
@@ -13,22 +13,25 @@ package scala.xml
*
* @param pre ...
* @param key ...
- * @param value the attribute value, which may not be null
+ * @param value the attribute value
* @param next ...
*/
class PrefixedAttribute(
val pre: String,
val key: String,
val value: Seq[Node],
- val next: MetaData)
+ val next1: MetaData)
extends Attribute
{
- if (value eq null)
- throw new UnsupportedOperationException("value is null")
+ val next = if (value ne null) next1 else next1.remove(key)
- /** same as this(key, Utility.parseAttributeValue(value), next) */
+ /** same as this(pre, key, Text(value), next), or no attribute if value is null */
def this(pre: String, key: String, value: String, next: MetaData) =
- this(pre, key, Text(value), next)
+ this(pre, key, if (value ne null) Text(value) else null: NodeSeq, next)
+
+ /** same as this(pre, key, value.get, next), or no attribute if value is None */
+ def this(pre: String, key: String, value: Option[Seq[Node]], next: MetaData) =
+ this(pre, key, value.orNull, next)
/** Returns a copy of this unprefixed attribute with the given
* next field.
View
2  src/library/scala/xml/UnprefixedAttribute.scala
@@ -22,7 +22,7 @@ extends Attribute
final val pre = null
val next = if (value ne null) next1 else next1.remove(key)
- /** same as this(key, Text(value), next) */
+ /** same as this(key, Text(value), next), or no attribute if value is null */
def this(key: String, value: String, next: MetaData) =
this(key, if (value ne null) Text(value) else null: NodeSeq, next)
View
2  src/library/scala/xml/Utility.scala
@@ -61,7 +61,7 @@ object Utility extends AnyRef with parsing.TokenTests {
val key = md.key
val smaller = sort(md.filter { m => m.key < key })
val greater = sort(md.filter { m => m.key > key })
- smaller.append( Null ).append(md.copy ( greater ))
+ smaller.copy(md.copy ( greater ))
}
/** Return the node with its attribute list sorted alphabetically
View
2  test/files/jvm/xml03syntax.check
@@ -23,4 +23,4 @@ true
4
node=<elem key="<b>hello</b>"></elem>, key=Some(<b>hello</b>)
-node=<elem ></elem>, key=None
+node=<elem></elem>, key=None
View
33 test/files/run/xml-attribute.scala
@@ -0,0 +1,33 @@
+import xml.Node
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val noAttr = <t/>
+ val attrNull = <t a={ null: String }/>
+ val attrNone = <t a={ None: Option[Seq[Node]] }/>
+ val preAttrNull = <t p:a={ null: String }/>
+ val preAttrNone = <t p:a={ None: Option[Seq[Node]] }/>
+ assert(noAttr == attrNull)
+ assert(noAttr == attrNone)
+ assert(noAttr == preAttrNull)
+ assert(noAttr == preAttrNone)
+
+ val noAttrStr = "<t></t>"
+ assert(noAttr.toString() == noAttrStr)
+ assert(attrNull.toString() == noAttrStr)
+ assert(attrNone.toString() == noAttrStr)
+ assert(preAttrNull.toString() == noAttrStr)
+ assert(preAttrNone.toString() == noAttrStr)
+
+ val xml1 = <t b="1" d="2"/>
+ val xml2 = <t a={ null: String } p:a={ null: String } b="1" c={ null: String } d="2"/>
+ val xml3 = <t b="1" c={ null: String } d="2" a={ null: String } p:a={ null: String }/>
+ assert(xml1 == xml2)
+ assert(xml1 == xml3)
+
+ val xml1Str = "<t d=\"2\" b=\"1\"></t>"
+ assert(xml1.toString() == xml1Str)
+ assert(xml2.toString() == xml1Str)
+ assert(xml3.toString() == xml1Str)
+ }
+}
Something went wrong with that request. Please try again.