Używam kompilacji w klasie JSON w Scala 2,8 do analizowania kodu JSON. Nie chcę korzystać z Liftweb jednego lub innego ze względu na zminimalizowanie zależności.
Sposób, w jaki to robię, wydaje się zbyt konieczny, czy jest lepszy sposób, aby to zrobić?
import scala.util.parsing.json._
...
val json:Option[Any] = JSON.parseFull(jsonString)
val map:Map[String,Any] = json.get.asInstanceOf[Map[String, Any]]
val languages:List[Any] = map.get("languages").get.asInstanceOf[List[Any]]
languages.foreach( langMap => {
val language:Map[String,Any] = langMap.asInstanceOf[Map[String,Any]]
val name:String = language.get("name").get.asInstanceOf[String]
val isActive:Boolean = language.get("is_active").get.asInstanceOf[Boolean]
val completeness:Double = language.get("completeness").get.asInstanceOf[Double]
}
JSON.parseFull
zwracaOption[Any]
, więc zaczyna się odList(None)
lubList(Some(any))
. SłużySome
do dopasowania wzorcaOption
.Oto sposób dopasowania wzorca:
źródło
Podoba mi się odpowiedź @ huynhjl, poprowadziła mnie właściwą ścieżką. Jednak nie radzi sobie dobrze z błędami. Jeśli żądany węzeł nie istnieje, otrzymasz wyjątek rzutowania. Dostosowałem to nieco,
Option
aby lepiej sobie z tym poradzić.Oczywiście nie tyle obsługuje to błędy, ile pozwala na ich uniknięcie. Spowoduje to utworzenie pustej listy, jeśli brakuje któregokolwiek z węzłów json. Możesz użyć a,
match
aby sprawdzić obecność węzła przed wykonaniem ...źródło
def unapply(a: Option[Any]): Option[T] = a.map(_.asInstanceOf[T])
.MatchError
zamiast tego dał (Scala 2.12). W tym celu konieczne było zawinięcie for w blok try / catch. Jakieś fajniejsze pomysły?Wypróbowałem kilka rzeczy, preferując dopasowywanie wzorców jako sposób na uniknięcie rzutowania, ale napotkałem problemy z usuwaniem typów w typach kolekcji.
Wydaje się, że głównym problemem jest to, że pełny typ wyniku analizy odzwierciedla strukturę danych JSON i jest albo uciążliwy, albo niemożliwy do pełnego określenia. Wydaje mi się, że dlatego Any jest używany do obcinania definicji typów. Używanie Any prowadzi do konieczności odlewania.
Zhakowałem poniżej coś, co jest zwięzłe, ale jest bardzo specyficzne dla danych JSON sugerowanych przez kod w pytaniu. Coś bardziej ogólnego byłoby bardziej satysfakcjonujące, ale nie jestem pewien, czy byłoby to bardzo eleganckie.
źródło
źródło
Możesz to zrobić! Bardzo łatwy do przeanalizowania kod JSON: P
źródło
Oto sposób, w jaki robię bibliotekę Scala Parser Combinator:
źródło