views:

1691

answers:

4

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?

+2  A: 

afaik there is no such thing. But you might want to take a look at sbinary

Eishay Smith
A: 

Nothing in Scala's native class library. But there is no shortage of Java libraries that will do this.

Rob H
A: 

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.

Tristan Juricek
+2  A: 

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.

  • Scala includes special support for processing XML.
  • Scala lets you type in XML as a literal anywhere that an expression is valid.
  • You can evaluate Scala code in the middle of of an XML literal by using curly braces ({}) as an escape.

So you can write something like:

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

The above evaluates to scala.xml.Elem = <a> 7 </a>.

  • If you want to find a sub-element by tag name, simply call \ with the name of the tag.
  • You can do a "deep search" and look through sub-sub-elements, etc. by using \\ 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.

eed3si9n
Thanks for the detailed answer. I want a generic solution though, where serialization code is written only once and not in every class in order to avoid boilerplate code and information duplication.
thSoft