JSON to XML in Scala and dealing with Option() result

前端 未结 4 2001
轻奢々
轻奢々 2021-01-23 01:25

Consider the following from the Scala interpreter:

scala> JSON.parseFull(\"\"\"{\"name\":\"jack\",\"greeting\":\"hello world\"}\"\"\")
res6: Option[Any] = Som         


        
4条回答
  •  执念已碎
    2021-01-23 01:48

    You have two separate problems.

    1. It's typed as Any.
    2. Your data is inside an 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(jackhi)
    

    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 value, 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(jackhi)
    

    (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).)

提交回复
热议问题