Je veux juste convertir une chaîne contenant un yaml en une autre chaîne contenant le json converti correspondant utilisant Java.
Par exemple, supposons que j'ai le contenu de cette yaml
---
paper:
uuid: 8a8cbf60-e067-11e3-8b68-0800200c9a66
name: On formally undecidable propositions of Principia Mathematica and related systems I.
author: Kurt Gödel.
tags:
- tag:
uuid: 98fb0d90-e067-11e3-8b68-0800200c9a66
name: Mathematics
- tag:
uuid: 3f25f680-e068-11e3-8b68-0800200c9a66
name: Logic
dans une chaîne appelée yamlDoc:
String yamlDoc = "---\npaper:\n uuid: 8a... etc...";
Je veux une méthode qui puisse convertir la chaîne yaml en une autre chaîne avec le json correspondant, c'est-à-dire le code suivant
String yamlDoc = "---\npaper:\n uuid: 8a... etc...";
String json = convertToJson(yamlDoc); // I want this method
System.out.println(json);
devrait imprimer:
{
"paper": {
"uuid": "8a8cbf60-e067-11e3-8b68-0800200c9a66",
"name": "On formally undecidable propositions of Principia Mathematica and related systems I.",
"author": "Kurt Gödel."
},
"tags": [
{
"tag": {
"uuid": "98fb0d90-e067-11e3-8b68-0800200c9a66",
"name": "Mathematics"
}
},
{
"tag": {
"uuid": "3f25f680-e068-11e3-8b68-0800200c9a66",
"name": "Logic"
}
}
]
}
Je veux savoir s'il existe quelque chose de similaire à la méthode convertToJson () dans cet exemple.
J'ai essayé d'y parvenir avec SnakeYAML , donc ce code
Yaml yaml = new Yaml();
Map<String,Object> map = (Map<String, Object>) yaml.load(yamlDoc);
construit une carte contenant la structure YAML analysée (à l'aide de cartes imbriquées). Ensuite, s’il existe un analyseur syntaxique capable de convertir une carte en chaîne json, cela résoudra mon problème, mais je n’ai rien trouvé de tel.
Toute réponse sera grandement appréciée.
Grâce au conseil HotLicks (dans les commentaires de la question), j'ai finalement réussi la conversion en utilisant les bibliothèques org.json et SnakeYAML de cette manière:
private static String convertToJson(String yamlString) {
Yaml yaml= new Yaml();
Map<String,Object> map= (Map<String, Object>) yaml.load(yamlString);
JSONObject jsonObject=new JSONObject(map);
return jsonObject.toString();
}
Je ne sais pas si c'est la meilleure façon de le faire, mais ça marche pour moi.
Voici une implémentation qui utilise Jackson:
String convertYamlToJson(String yaml) {
ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory());
Object obj = yamlReader.readValue(yaml, Object.class);
ObjectMapper jsonWriter = new ObjectMapper();
return jsonWriter.writeValueAsString(obj);
}
A besoin:
compile('com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.7.4')
Un grand merci à Miguel A. Carrasco, il a effectivement résolu le problème. Mais sa version est restrictive. Son code échoue si root est une liste ou une valeur primitive. La solution la plus générale est:
private static String convertToJson(String yamlString) {
Yaml yaml= new Yaml();
Object obj = yaml.load(yamlString);
return JSONValue.toJSONString(obj);
}
J'ai trouvé que l'exemple ne produisait pas des valeurs correctes lors de la conversion de Swagger (OpenAPI) YAML en JSON. J'ai écrit la routine suivante:
private static Object _convertToJson(Object o) throws JSONException {
if (o instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) o;
JSONObject result = new JSONObject();
for (Map.Entry<Object, Object> stringObjectEntry : map.entrySet()) {
String key = stringObjectEntry.getKey().toString();
result.put(key, _convertToJson(stringObjectEntry.getValue()));
}
return result;
} else if (o instanceof ArrayList) {
ArrayList arrayList = (ArrayList) o;
JSONArray result = new JSONArray();
for (Object arrayObject : arrayList) {
result.put(_convertToJson(arrayObject));
}
return result;
} else if (o instanceof String) {
return o;
} else if (o instanceof Boolean) {
return o;
} else {
log.error("Unsupported class [{0}]", o.getClass().getName());
return o;
}
}
Ensuite, je pourrais utiliser SnakeYAML pour charger et afficher le JSON avec les éléments suivants:
Yaml yaml= new Yaml();
Map<String,Object> map= (Map<String, Object>) yaml.load(yamlString);
JSONObject jsonObject = (JSONObject) _convertToJson(map);
System.out.println(jsonObject.toString(2));
Merci Miguel! Votre exemple a beaucoup aidé. Je ne voulais pas utiliser la bibliothèque 'JSON-Java'. Je préfère GSON. Mais il n'a pas été difficile de traduire la logique de JSON-Java vers le modèle de domaine de GSON. Une seule fonction peut faire l'affaire:
/**
* Wraps the object returned by the Snake YAML parser into a GSON JsonElement
* representation. This is similar to the logic in the wrap() function of:
*
* https://github.com/stleary/JSON-Java/blob/master/JSONObject.Java
*/
public static JsonElement wrapSnakeObject(Object o) {
//NULL => JsonNull
if (o == null)
return JsonNull.INSTANCE;
// Collection => JsonArray
if (o instanceof Collection) {
JsonArray array = new JsonArray();
for (Object childObj : (Collection<?>)o)
array.add(wrapSnakeObject(childObj));
return array;
}
// Array => JsonArray
if (o.getClass().isArray()) {
JsonArray array = new JsonArray();
int length = Array.getLength(array);
for (int i=0; i<length; i++)
array.add(wrapSnakeObject(Array.get(array, i)));
return array;
}
// Map => JsonObject
if (o instanceof Map) {
Map<?, ?> map = (Map<?, ?>)o;
JsonObject jsonObject = new JsonObject();
for (final Map.Entry<?, ?> entry : map.entrySet()) {
final String name = String.valueOf(entry.getKey());
final Object value = entry.getValue();
jsonObject.add(name, wrapSnakeObject(value));
}
return jsonObject;
}
// everything else => JsonPrimitive
if (o instanceof String)
return new JsonPrimitive((String)o);
if (o instanceof Number)
return new JsonPrimitive((Number)o);
if (o instanceof Character)
return new JsonPrimitive((Character)o);
if (o instanceof Boolean)
return new JsonPrimitive((Boolean)o);
// otherwise.. string is a good guess
return new JsonPrimitive(String.valueOf(o));
}
Ensuite, vous pouvez analyser un JsonElement à partir d'une chaîne YAML avec:
Yaml yaml = new Yaml();
Map<String, Object> yamlMap = yaml.load(yamlString);
JsonElement jsonElem = wrapSnakeObject(yamlMap);
et l'imprimer avec:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println(gson.toJson(jsonElem));
J'étais dirigé vers cette question lorsque je cherchais une solution au même problème.
Je suis également tombé sur l'article suivant https://dzone.com/articles/read-yaml-in-Java-with-jackson
Il semble que la bibliothèque JSON de Jackson ait une extension YAML basée sur SnakeYAML . Comme Jackson est l’une des bibliothèques de facto pour JSON, j’ai pensé que je devrais faire le lien ici.