2012-03-01 21 views
7

Para un fragmento de XML como esto:XML a JSON con Scala

val fruits = 
<fruits> 
    <fruit> 
    <name>apple</name> 
    <taste>ok</taste> 
    </fruit> 
    <fruit> 
    <name>banana</name> 
    <taste>better</taste> 
    </fruit> 
</fruits> 

hacer algo como:

fruits \\ "fruit" 

devolverá una secuencia de tipo scala.xml.NodeSeq con todas las frutas y subnodos en el interior.

¿Cuál es la mejor manera de convertir esto en una lista de objetos JSON? Estoy intentando enviar mi lista de frutas a un navegador. Eché un vistazo a scala.util.parsing.json.JSONObject y scala.util.parsing.json.JSONArray, pero no sé cómo llegar desde NodeSeq a cualquiera de estos últimos.

Si es posible, me gustaría ver cómo se hace con el código Scala normal.

Respuesta

14

This podría ser relevante. Aquí está mi solución utilizando spray-json:

import scala.xml._ 
import cc.spray.json._ 
import cc.spray.json.DefaultJsonProtocol._ 

implicit object NodeFormat extends JsonFormat[Node] { 
    def write(node: Node) = 
    if (node.child.count(_.isInstanceOf[Text]) == 1) 
     JsString(node.text) 
    else 
     JsObject(node.child.collect { 
     case e: Elem => e.label -> write(e) 
     }: _*) 

    def read(jsValue: JsValue) = null // not implemented 
} 

val fruits = 
    <fruits> 
    <fruit> 
     <name>apple</name> 
     <taste> 
     <sweet>true</sweet> 
     <juicy>true</juicy> 
     </taste> 
    </fruit> 
    <fruit> 
     <name>banana</name> 
     <taste>better</taste> 
    </fruit> 
    </fruits> 

val json = """[{"name":"apple","taste":{"sweet":"true","juicy":"true"}},{"name":"banana","taste":"better"}]""" 

assert((fruits \\ "fruit").toSeq.toJson.toString == json) 
+1

Esto se ve muy bien, pero la muestra no se ejecuta. Obtengo lo siguiente: error: no encontrado: valor JsField. – Jack

+0

@JacobusR Vaya, aún usando la versión 1.0.1 de spray-json. De hecho, no hay clase 'JsField' en 1.1.0. Lo reemplazó con una tupla. – elbowich

+0

Funciona como un encanto, gracias. Siempre es agradable obtener un bit de código ejecutable, en lugar de solo un fragmento (+1 para eso :-). – Jack

2

Creo que debería usar ScalaXB para convertir el XML en clases scala y luego escribir los bits toJson apropiados para dar salida a Json.

Debería ser un placer.

+5

El problema con ScalaXB es que requiere de esquemas XML –