2009-04-16 18 views
7

Al ver el poder de Scala, me pregunto si un gráfico de objetos arbitrarios podría ser serializado y deserializado a/desde XML utilizando funciones y bibliotecas de lenguaje Scala incorporadas (por ejemplo, sin XMLEncoder, XStream o JAXB). Lamentablemente, no he encontrado tal solución. ¿Qué podrías aconsejar?serialización de Scala XML

Respuesta

4

afaik no existe tal cosa. Pero es posible que desee echar un vistazo a sbinary

0

Nada en la biblioteca de clases nativa de Scala. Pero no hay escasez de bibliotecas Java que hagan esto.

1

En términos de "asesoramiento", hemos estado utilizando las bibliotecas nativas para muchos archivos de configuración rápidos y sucios. La principal ventaja es que el código de "análisis sintáctico" se usa para agregar buenos mensajes de error. De esta manera:

val xml = xml.XML.load(source) 

val required = (xml \ "value").firstOption match { 
    case None => error("The value element is missing, or should I be a default?") 
    case Some(req) => req 
} 

Aquí es donde generalmente utilicé algo así como XStream, por lo que no fue un gran cambio. No estoy seguro si podría obtener el mensaje de error + manejo predeterminado en su marco de deserialización con una biblioteca.

8

No sé "si un gráfico de objetos arbitrario podría ser serializado y deserializado a/desde XML utilizando funciones y bibliotecas de lenguaje Scala incorporadas", pero dado que hay compatibilidad nativa para XML en Scala, lo haré mencionalos. Se pueden encontrar más detalles en el cap. 26 de Programming in Scala llamados Trabajo con XML:

Este capítulo presenta apoyo de Scala para XML. Después de discutir datos semi-estructurados en general, muestra la funcionalidad esencial en Scala para manipular XML: cómo hacer nudos con los literales XML, cómo guardar y cargar XML para archivos, y cómo desarmar nodos XML utilizando los métodos de consulta y coincidencia de patrones.

Para resumir rápidamente el capítulo, citaré algunos puntos clave.

  • Scala incluye soporte especial para el procesamiento de XML.
  • Scala le permite escribir en XML como un literal donde sea que una expresión sea válida.
  • Puede evaluar el código de Scala en medio de un literal XML utilizando llaves ({}) como escape.

para que pueda escribir algo como:

val foo = <a> {3 + 4} </a> 

Las evalúa arriba para scala.xml.Elem = <a> 7 </a>.

  • Si desea encontrar un subelemento por nombre de etiqueta, simplemente llame al \ con el nombre de la etiqueta.
  • Puede hacer una "búsqueda profunda" y examinar los sub-subelementos, etc. mediante el uso de \\ en lugar del operador \.

El libro tiene un ejemplo de serialización y deserialización de una clase abstracta, pero es escrito a mano:

abstract class CCTherm { 
    val description: String 
    val yearMade: Int 

    def toXML = 
    <cctherm> 
     <description>{description}</description> 
     <yearMade>{yearMade}</yearMade> 
    </cctherm> 

    def fromXML(node: scala.xml.Node): CCTherm = 
    new CCTherm { 
     val description = (node \ "description").text 
     val yearMade = (node \ "yearMade").text.toInt 
    }  
} 

también más información se puede encontrar en un proyecto de libro llamado scala.xml.

+0

Gracias por la respuesta detallada. Sin embargo, quiero una solución genérica, donde el código de serialización se escriba solo una vez y no en todas las clases para evitar el código repetitivo y la duplicación de información. – thSoft

3

En el net.liftweb.json paquete, xml objeto, encuentro la siguiente función:

def toXml(json: JValue): NodeSeq = { 
    def toXml(name: String, json: JValue): NodeSeq = json match { 
     case JObject(fields) => new XmlNode(name, fields flatMap { f => toXml(f.name, f.value) }) 
     case JArray(xs) => xs flatMap { v => toXml(name, v) } 
     case JField(n, v) => new XmlNode(name, toXml(n, v)) 
     case JInt(x) => new XmlElem(name, x.toString) 
     case JDouble(x) => new XmlElem(name, x.toString) 
     case JString(x) => new XmlElem(name, x) 
     case JBool(x) => new XmlElem(name, x.toString) 
     case JNull => new XmlElem(name, "null") 
     case JNothing => Text("") 
    } 

    json match { 
     case JField(n, v) => toXml(n, v) 
     case JObject(fields) => fields flatMap { f => toXml(f.name, f.value) } 
     case x => toXml("root", x) 
    } 
    } 

hay un paquete de extracción que tiene funciones para convertir al menos las clases de casos a JSON. Junto con toXml, esto podría convertir muchos tipos de datos a XML.