scala-xml
scala-xml copied to clipboard
Surprising filter on node failure
With the following code:
https://gist.github.com/fancellu/03bb694c920898613795
So as you can see, with hard coded XML, the filter works fine. With a seemingly equivalent structure, it doesn't find anything.
Probably due to different hashCodes, even though elements render the same
(root"number").hashCode //> Int = 1598709610 (root2"number").hashCode //> Int = 1439920665
(root"number").head.text==(root2"number").head.text //> Boolean=true
scala> val a = <number>{2}</number>
a: scala.xml.Elem = <number>2</number>
scala> val b = <number>2</number>
b: scala.xml.Elem = <number>2</number>
scala> a == b
res0: Boolean = false
scala> (a.hashCode, b.hashCode)
res0: (Int, Int) = (-1257096872,361570984)
Thanks William, back to my version, you can "fix" by stringifying then loading back. Ha! (I'm cringing)
(scala.xml.XML.loadString(root2.toString) "number").filter(find2)
So that is why when you're getting your XML from a string/url/file/dom, it will be fine, its just the Scala escaped stuff which seems broken.
Or. generate like this:
val root2=
{x} emits an Atom. But renders the same. Either way, it doesn't follow the principle of least surprise
package com.scalawilliam.examples
object Equality extends App {
val a = <number>{2}</number>
val b = <number>2</number>
println(a.xml_==(b))
println(a.equals(b))
println(a == b)
println((<numbers><number>{2}</number><number>2</number></numbers> \ "number").distinct)
}
false
false
Set(<number>2</number>, <number>2</number>)
package com.scalawilliam.examples
object Equality extends App {
val number = <numbers><number>{2}</number><number>2</number></numbers> \ "number"
val numbers = for {
item <- number
i <- item
j <- i
node <- j.child
} yield (node, node.hashCode(), node.getClass.getName, node.map(_.asInstanceOf[scala.xml.Atom[_]].data.getClass.getName))
numbers foreach println
}
(2,-548373507,scala.xml.Atom,List(java.lang.Integer))
(2,-301266488,scala.xml.Text,List(java.lang.String))
<node>{2}</node> == <node>2</node>
> false
<node>{Text(2.toString)}</node> == <node>2</node>
> true
<node>{2}</node> == <node>{2}</node>
>true
So if using XML literals and curly braces to inject values, best test against similar escaped value, and not what looks the same when serialized.
get caught by it.
ant chance to fix it? it's too surprising. i was wondering what happened and spent 1-2 hrs on this.
@HuStmpHrrr pull request welcome. this repo is community-maintained, the only fixes coming in these days are coming from the community.