2010-04-09 16 views
12

En primer lugar: Estoy en Scala 2,8Scala Patrón XML a juego y atributos

Tengo un pequeño problema durante el uso de patrones sobre los elementos XML. Sé que puedo hacer algo como esto:

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

Este es el tipo de ejemplo que encuentro en todas partes en la red y en mis dos libros Scala. Pero, ¿qué ocurre si quiero hacer coincidir un elemento XML según un atributo?

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 _ => 
} 

El compilador generará un error: in XML literal: '>' expected instead of 't' a mí, lo que indica que no puedo usar atributos porque el compilador espera que la etiqueta de elemento a ser cerrado. Si trato de hacer coincidir un elemento XML con un atributo fijo, sin llaves, se produce el mismo error.

Así que mi pregunta es simple: ¿Cómo puedo hacer una coincidencia? ¿Debo crear un Elem para la coincidencia en lugar de utilizar esos agradables literales? Y si: ¿Cuál es la mejor manera de hacerlo?

Respuesta

17

El manejo de los atributos es mucho más doloroso de lo que debería ser. Este ejemplo particular muestra, de hecho, que Scala no deconstruye los XML de la misma manera que los construye, ya que esta sintaxis es válida para los literales XML. De todos modos, aquí hay una forma:

myXML match { 
    case <a>{b @ <b>{theText}</b>}</a> => 
    println("An %s text: %s".format(b \ "@type", theText)) 
} 
+0

Supongo que será aún más doloroso tener un caso en el que solo los nodos donde el atributo de tipo tenga un determinado valor coincida. :-(¿Estoy en lo cierto? – Malax

+3

@Malax No realmente, solo agregue 'if b \" @type "== Text (" whatever ")' before '=>' O, como alternativa, 'if (b \" @type ") .toString ==" lo que sea "'. –

Cuestiones relacionadas