Matt R
Matt R

Reputation: 10503

Scala XML pattern with whitespace

Is there a value of xml which will match the following pattern?

xml match { case <foo> { x } </foo> => 42 }

Upvotes: 3

Views: 313

Answers (1)

Matthew Farwell
Matthew Farwell

Reputation: 61705

Yes.

scala> val x = 33
x: Int = 33

scala> val xml = <foo> { x } </foo>
xml: scala.xml.Elem = <foo> 33 </foo>

scala> xml match { case <foo> { x } </foo> => 42 }
res0: Int = 42

I think where your confusion comes in is it doesn't match against <foo> 33 </foo>

scala> <foo> 33 </foo> match { case <foo> { x } </foo> => 42 }
scala.MatchError: <foo> 33 </foo> (of class scala.xml.Elem)

This is because when you use the {}, scala inserts extra elements for the spaces before and after the {}, so you get three elements, not one. You can see this by calling unapplySeq (which is what is used for the pattern matching):

scala> scala.xml.Elem.unapplySeq(<foo> 33 </foo>)
res4: Option[(String, String, scala.xml.MetaData, scala.xml.NamespaceBinding, Seq[scala.xml.Node])] =
    Some((null,foo,,,ArrayBuffer( 33 )))

scala> scala.xml.Elem.unapplySeq(<foo> { x } </foo>)
res5: Option[(String, String, scala.xml.MetaData, scala.xml.NamespaceBinding, Seq[scala.xml.Node])] =
    Some((null,foo,,,ArrayBuffer( , 33,  )))

Notice in the second example, you're getting three elements in the ArrayBuffer, and only one in the first. So the pattern doesn't match correctly.

Upvotes: 5

Related Questions