У вас есть две отдельные проблемы.
- Он напечатан как
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
).)