Reputation: 22660
Seeing the power of Scala, I wonder if an arbitrary object graph could be serialized and deserialized to/from XML using built-in Scala language features and libraries (e.g. without XMLEncoder, XStream or JAXB). Unfortunately, I haven't found such a solution. What could you advise?
Upvotes: 7
Views: 8387
Reputation: 31
In the package net.liftweb.json, object xml, I find the following function:
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)
}
}
There is an Extraction package that has functions to convert at least case classes to JSON. Together with toXml, this might convert many data types to XML.
Upvotes: 3
Reputation: 95624
I don't know "if an arbitrary object graph could be serialized and deserialized to/from XML using built-in Scala language features and libraries," but since there are some native support for XML in Scala, I'll mention them. More detail could be found in Ch. 26 of Programming in Scala called Working with XML:
This chapter introduces Scala's support for XML. After discussing semi-structured data in general, it shows the essential functionality in Scala for manipulating XML: how to make nodes with XML literals, how to save and load XML to files, and how to take apart XML nodes using query methods and pattern matching.
To quickly summarize the chapter, I'll quote some key points.
So you can write something like:
val foo = <a> {3 + 4} </a>
The above evaluates to scala.xml.Elem = <a> 7 </a>
.
\
with the name of the tag.\\
instead of the \
operator.The book has an example of serialization and deserialization of an abstract class, but it's hand-written:
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
}
}
Also more info could be found in a draft book called scala.xml.
Upvotes: 8
Reputation: 1814
In terms of "advice", we've been using the native libraries for many quick-and-dirty configuration files. The major advantage is that the "parsing" code is used to add nice error messages. Like this:
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
}
This is where I typically used something like XStream, so it wasn't a big switch. I'm not sure if you could get the error message + default handling on your deserialization framework with a library.
Upvotes: 1
Reputation: 14982
Nothing in Scala's native class library. But there is no shortage of Java libraries that will do this.
Upvotes: 0
Reputation: 1137
afaik there is no such thing. But you might want to take a look at sbinary
Upvotes: 4