Consider the following from the Scala interpreter:
scala> JSON.parseFull(\"\"\"{\"name\":\"jack\",\"greeting\":\"hello world\"}\"\"\")
res6: Option[Any] = Som
You have two separate problems.
Any
.Option
and a Map
.Let's suppose we have the data:
val x: Option[Any] = Some(Map("name" -> "jack", "greeting" -> "hi"))
and suppose that we want to return the appropriate XML if there is something to return, but not otherwise. Then we can use collect
to gather those parts that we know how to deal with:
val y = x collect {
case m: Map[_,_] => m collect {
case (key: String, value: String) => key -> value
}
}
(note how we've taken each entry in the map apart to make sure it maps a string to a string--we wouldn't know how to proceed otherwise. We get:
y: Option[scala.collection.immutable.Map[String,String]] =
Some(Map(name -> jack, greeting -> hi))
Okay, that's better! Now if you know which fields you want in your XML, you can ask for them:
val z = for (m <- y; name <- m.get("name"); greet <- m.get("greeting")) yield {
{name} {greet}
}
which in this (successful) case produces
z: Option[scala.xml.Elem] =
Some(jack hi )
and in an unsuccessful case would produce None
.
If you instead want to wrap whatever you happen to find in your map in the form
, it's a bit more work because Scala doesn't have a good abstraction for tags:
val z = for (m <- y) yield { m.map { case (tag, text) => xml.Elem(null, tag, xml.Null, xml.TopScope, xml.Text(text)) }}
which again produces
z: Option[scala.xml.Elem] =
Some(jack hi )
(You can use get
to get the contents of an Option
, but it will throw an exception if the Option
is empty (i.e. None
).)