3

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

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

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Righty, thanks! It's also very handy to know about Elem.unapplySeq.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.