Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML to JSON with Scala

Tags:

scala

For a XML snippet like this:

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

doing something like:

fruits \\ "fruit"

will return a sequence of type scala.xml.NodeSeq with all the fruits and sub nodes inside.

What is the best way to convert this to a list of JSON objects? I'm trying to send my list of fruits back to a browser. I had a look at scala.util.parsing.json.JSONObject and scala.util.parsing.json.JSONArray, but I don't know how to get from NodeSeq to anyone of the latter.

If at all possible, I would love to see how it's done with plain Scala code.

like image 220
Jack Avatar asked Mar 01 '12 13:03

Jack


1 Answers

This might be relevant. Here is my solution using 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)
like image 62
elbowich Avatar answered Oct 08 '22 15:10

elbowich