Is this a bug in scala.xml.Elem?

Matching a [String] set with attributes Set [Elem] works fine with a single attribute, but it seems that with multiple attributes it is reset with one of them:

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] = Set(<X k="SSS" w="A"></X>) 

What happened to B and C?

Or is my understanding of peers at Elems wrong?

+4
source share
2 answers

This seems like a mistake, albeit a very strange one. I would have guessed that this is a mistake in Set , not Elem , but I cannot speak with any authority at this point.

+2
source

I think the problem is xml.MetaData or its subclass xml.Attribute . When comparing two Elem s, it is checked for equality of the xml prefix, label, attributes, and child Node elements.

Now xml.MetaData looks like a strange implementation under it, it contains itself and at the same time a linked list of attributes. This means, for example:

 scala >val elem = <ex="a" y="b"></e> elem: scala.xml.Elem = <ey="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") 

eg. it generates a list from itself with the head attribute removed.

An equality check in MetaData looks like this:

 this.toSet == other.toSet 

which works fine but is overridden in the Attribute class. (We do not 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) 

What would be good if the attribute list was converted to Set earlier, but this is not so, and therefore only the first element in the attribute list is checked for equality. And thus, if the head element in the internal linked attribute list is the same element for two xml.Elem s, they will be equal.

+1
source

Source: https://habr.com/ru/post/1334264/


All Articles