开发者

Is this a bug in scala.xml.Elem?

Mapping a Set[String] to attributes of a Set[Elem] works fine with one attribute, but seems to fail with multiple attributes when one of them is shared:

scala> val s1=Set("A","B","C")
s1: scala.collection.immutable.Set[java.lang.String] = Set(A, B, C)

scala> s1.map((a:String)=>{<X w={a}></X>})
res3: scala.collection.immutable.Set[scala.xml.Elem] = Set(<X w="A"></X>, <X w="B"></X>, <X w="C"></X>)

scala> s1.map((a:String)=>{<X w={a} k="SSS"></X>})
res4: scala.collection.immutable.Set[scala.xml.Elem] = Se开发者_运维技巧t(<X k="SSS" w="A"></X>)

What happened to B & C?

Or is my understanding of equals on Elems wrong?


This does appear to be a bug, albeit a very strange one. I would guess it's a bug in Set and not Elem, but I can't speak with any authority on that point.


I think the problem lies in xml.MetaData or its subclass xml.Attribute. When comparing two Elems, it is checked for equality of the xml prefix, the label, the attributes and the Node’s children.

Now, xml.MetaData has kind of a strange implementation underneath, it contains itself and at the same time a linked list of attributes. That means that, for example:

scala >val elem = <e x="a" y="b"></e>
elem: scala.xml.Elem = <e y="b" x="a"></e>

scala> elem.attributes
res50: scala.xml.MetaData =  y="b" x="a"

scala> elem.attributes.toSet
res51: Set[scala.xml.MetaData] = Set( y="b" x="a",  x="a")

E.g. it generates a list of itself with the head attribute removed.

The equality check in MetaData looks like this

this.toSet == other.toSet

which works okay but is overridden in the Attribute class. (We can’t see it in the REPL, but our elem.attributes really is an Attribute.) There, the code only does this

(this.pre == other.pre) && (this.key == other.key) && (this.value sameElements other.value)

Which would be fine, if the attributes list were converted to a Set before but it isn’t and so only the first element in the attributes list is checked for equality. And thus, if the head element in the internal linked list of attributes happens to be the same element for two xml.Elems, they will be equal.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜