你有两个不同的问题。
- 输入为
Any。
- 您的数据位于
Option 和Map 中。
假设我们有数据:
val x: Option[Any] = Some(Map("name" -> "jack", "greeting" -> "hi"))
并假设如果有要返回的内容,我们想要返回适当的 XML,否则不返回。然后我们可以使用collect 来收集我们知道如何处理的部分:
val y = x collect {
case m: Map[_,_] => m collect {
case (key: String, value: String) => key -> value
}
}
(请注意我们如何将映射中的每个条目分开以确保它将字符串映射到字符串——否则我们将不知道如何进行。我们得到:
y: Option[scala.collection.immutable.Map[String,String]] =
Some(Map(name -> jack, greeting -> hi))
好的,这样更好!现在,如果您知道您想要在 XML 中包含哪些字段,您可以询问它们:
val z = for (m <- y; name <- m.get("name"); greet <- m.get("greeting")) yield {
<test><name>{name}</name><greeting>{greet}</greeting></test>
}
在这个(成功的)案例中产生了
z: Option[scala.xml.Elem] =
Some(<test><name>jack</name><greeting>hi</greeting></test>)
在不成功的情况下会产生None。
如果您想以<key>value</key> 的形式包装您在地图中发现的任何内容,则工作量会更大一些,因为 Scala 对标签没有很好的抽象:
val z = for (m <- y) yield <test>{ m.map { case (tag, text) => xml.Elem(null, tag, xml.Null, xml.TopScope, xml.Text(text)) }}</test>
再次产生
z: Option[scala.xml.Elem] =
Some(<test><name>jack</name><greeting>hi</greeting></test>)
(您可以使用get 获取Option 的内容,但如果Option 为空(即None)则会抛出异常。)