在Scala中使用JSON到XML并处理Option()结果

Jac*_*ack 2 scala scala-option

请考虑Scala解释器中的以下内容:

scala> JSON.parseFull("""{"name":"jack","greeting":"hello world"}""")
res6: Option[Any] = Some(Map(name -> jack, greeting -> hello world))
Run Code Online (Sandbox Code Playgroud)

为什么在Some()中返回Map?我该如何使用它?

我想将值放在xml模板中:

<test>
  <name>name goes here</name>
  <greeting>greeting goes here</greeting>
</test>
Run Code Online (Sandbox Code Playgroud)

将Scala从Some(thing)中取出并在xml中获取这些值的Scala方法是什么?

oxb*_*kes 6

你应该使用这样的东西:

res6 collect { case x: Map[String, String] => renderXml(x) }
Run Code Online (Sandbox Code Playgroud)

哪里:

def renderXml(m: Map[String, String]) = 
  <test><name>{m.get("name") getOrElse ""}</name></test>
Run Code Online (Sandbox Code Playgroud)

采用a 和的collect方法是(通过谓词)和(通过函数)的组合.那是:Option[A]PartialFunction[A, B]filtermap

opt collect pf
opt filter (a => pf isDefinedAt a) map (a => pf(a))
Run Code Online (Sandbox Code Playgroud)

两者都是等价的.当你有一个可选的值,你应该使用map,flatMap,filter,collect等改造选项在你的程序,避免提取或者通过模式匹配,或者通过该选项的内容,get方法.你应该永远,永远使用Option.get-它是规范的标志,你做错了.应该避免模式匹配,因为它代表了程序中的一个分支,因此增加了圈复杂性 - 你可能希望这样做的唯一时间可能是性能


实际上你有一个问题,即parseJSON方法的结果是一个Option[Any](原因是,它Option可能是解析可能不成功,并且Option是一种更优雅的处理方式,null而且,好吧null).

但上面代码的问题是case x: Map[String, String]由于类型擦除而无法在运行时检查(即scala可以检查该选项是否包含Map但不是Map两个类型参数String.代码将为您提供未经检查的警告.


fot*_*ton 6

一个Option是返回,因为parseFull有不同的可能的返回值取决于输入,或者它可能无法在所有的(给解析输入None).因此,除了将Map键与值相关联的可选项之外,List如果JSON字符串表示数组,则还可以返回可选项.

例:

scala> import scala.util.parsing.json.JSON._
import scala.util.parsing.json.JSON._

scala> parseFull("""{"name":"jack"}""")
res4: Option[Any] = Some(Map(name -> jack))

scala> parseFull("""[ 100, 200, 300 ]""")
res6: Option[Any] = Some(List(100.0, 200.0, 300.0))
Run Code Online (Sandbox Code Playgroud)

您可能需要模式匹配才能实现您想要的效果,如下所示:

scala> parseFull("""{"name":"jack","greeting":"hello world"}""") match {
     |   case Some(m) => Console println ("Got a map: " + m)
     |   case _ =>
     | }
Got a map: Map(name -> jack, greeting -> hello world)
Run Code Online (Sandbox Code Playgroud)

现在,如果要生成XML输出,可以使用上面的内容来迭代键/值对:

import scala.xml.XML

parseFull("""{"name":"jack","greeting":"hello world"}""") match {
  case Some(m: Map[_,_]) =>
    <test>
      {
        m map { case (k,v) =>
          XML.loadString("<%s>%s</%s>".format(k,v,k))
        }
      }
    </test>

  case _ =>
}
Run Code Online (Sandbox Code Playgroud)


sep*_*p2k 5

parseFull返回一个Option因为该字符串可能不是有效的JSON(在这种情况下它将返回None而不是Some).

从a中获取值的通常方法Some是对其进行模式匹配,如下所示:

result match {
    case Some(map) =>
        doSomethingWith(map)
    case None =>
        handleTheError()
}
Run Code Online (Sandbox Code Playgroud)

如果您确定输入始终有效,因此您不需要处理无效输入的情况,您可以使用该get方法Option,这将在调用时引发异常None.