Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Surprising filter on node failure #25

Open
fancellu opened this issue Apr 28, 2014 · 7 comments
Open

Surprising filter on node failure #25

fancellu opened this issue Apr 28, 2014 · 7 comments

Comments

@fancellu
Copy link

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

@ScalaWilliam
Copy link

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)

@fancellu
Copy link
Author

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=
{for (x<- 1 to 3) yield {scala.xml.Text(x.toString)}}

{x} emits an Atom. But renders the same. Either way, it doesn't follow the principle of least surprise

@ScalaWilliam
Copy link

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>)

@ScalaWilliam
Copy link

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))

@fancellu
Copy link
Author

   <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.

@adriaanm adriaanm added this to the 1.0.4 milestone Dec 4, 2014
@HuStmpHrrr
Copy link

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.

@SethTisue
Copy link
Member

@HuStmpHrrr pull request welcome. this repo is community-maintained, the only fixes coming in these days are coming from the community.

@SethTisue SethTisue removed this from the 1.0.4 milestone Feb 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants