Je souhaite utiliser ujson de la bibliothèque upickle pour extraire une chaîne facultative d'un document json. Dans certains documents, le champ json existe, dans d'autres non.
Lorsque j'accède au champ et que le champ n'existe pas, j'obtiens une NoSuchElementException:
val json = ujson.read(jsonString)
json("attributename").str
results in: java.util.NoSuchElementException: key not found: attributename
Quelle est la manière idiomatique gérer les attributs json facultatifs dans ujson?
5 Réponses :
Je ne suis pas sûr, mais je cherchais le dépôt GitHub ici
Il semble qu'à la ligne 62 et de la ligne 87 à la ligne 99, il suffit d'appeler x.obj (i) .
Il n'effectue aucune vérification, il suffit de l'appeler. Cela a conduit à une java.util.NoSuchElementException parce que vous essayez d'accéder sans vérification. Je n'ai vu aucune version pour obtenir l'option, ni même pour vérifier si cette valeur existe.
Je suggérerais de passer par un idiome Try / Success / Failure sur scala
val tryAttr = Try{json("attributename").str}
tryAttr match {
case Success(_) => doYourThing
case Failure(t: NoSuchElementException) => DoSomethingElse
}
Si vous souhaitez renvoyer la valeur par défaut en cas d'exception, vous pouvez utiliser Try avec getOrElse:
val result = Try(json("attributename").str).getOrElse("defaultValue")
Le résultat sera être la valeur de la clé attributename ou de la chaîne defaultValue s'il n'y a pas de telle clé.
Je pense que la manière idiomatique est d'avoir une classe de cas au lieu d'aller manuellement contre le JSON AST.
Dans votre classe de cas, vous pourriez alors avoir un champ Option [String] .
json.obj.value.get("attributename").map(_.str)
Mais d'après l'apparence de celui-ci, vous pouvez faire
case class MyModel( attributeName: Option[String] ) implicit val rw: ReadWriter[MyModel] = macroRW read[MyModel](jsonString)
pour récupérer une Option [String] .
N'oubliez pas, un json est un objet.
Nous pouvons donc le vérifier comme ceci:
json.obj.keySet
Et btw, vous pouvez obtenir le keySet comme ceci :
val json = ujson.read(jsonString)
if (json.obj.get("attributename").nonEmpty) {
json("attributename").str
...
}