views:

422

answers:

2

Hi StackOverflow Community!

First of all: I'm at Scala 2.8

I have a slight Issue while using pattern matching on XML elements. I know I can do smth. like this:

val myXML = <a><b>My Text</b></a>
myXML match {
    case <a><b>{theText}</b></a> => println(theText)
    case _ =>
}

This is the sort of example I find everywhere on the net and in both of my Scala books. But what if I want to match on an XML element depending on an attribute?

val myXML = <a><b type="awesome">An awesome Text!</b></a>
myXML match {
    case <a><b type={textType}>{theText}</b><a> => println("An %s text: %s".format(textType, theText))
    case _ => 
}

The compiler will throw an error: in XML literal: '>' expected instead of 't' at me, indicating that I cannot use attributes because the compiler expected the element tag to be closed. If I try to match an XML element with a fixed attribute, without curly braces, the same error raises.

So my question is simple: How can I do such a match? Do I have to create an Elem for the match instead of using those nice literals? And if: What is the best way to do it?

+5  A: 

Handling attributes is way more of a pain that it should. This particular example shows, in fact, that Scala doesn't deconstruct XMLs the same way it constructs them, as this syntax is valid for XML literals. Anyway, here's a way:

myXML match { 
  case <a>{b @ <b>{theText}</b>}</a> => 
    println("An %s text: %s".format(b \ "@type", theText))
}
Daniel
I guess it will be even more painful to have a case where only nodes where the type attribute has a certain value matches. :-( Am I right?
Malax
@Malax Not really, just add `if b \ "@type" == Text("whatever")` before `=>`. Or, alternatively, `if (b \ "@type").toString == "whatever"`.
Daniel
A: 

@Daniel you said to insert

if b \ "@type" == Text("whatever") before =>

I tried that I keep getting errors does it make sense to have an if after a "case" ? can you please write the full syntax ?

Thanks I appreciate in advance

silverman