Il existe une pléthore de langages
pour décrire des données structurées.
À noter que JSON doit son origine, et son nom complet
(
Contrairement à JavaScript, JSON n'est
pas un langage de programmation, seulement un langage de
description de données, et il ne peut donc pas servir de véhicule
pour du
Voici un exemple, tiré du RFC, d'un objet exprimé en JSON :
{
"Image": {
"Width": 800,
"Height": 600,
"Title": "View from 15th Floor",
"Thumbnail": {
"Url": "http://www.example.com/image/481989943",
"Height": 125,
"Width": "100"
},
"IDs": [116, 943, 234, 38793]
}
}
Les détails de syntaxe sont dans la section 2 du RFC. Cet objet
d'exemple a un seul champ,
"Hello world!"
est un texte JSON légal (composé d'une chaîne de caractères en tout
et pour tout). Une des conséquences est qu'un lecteur de JSON qui lit au fil de l'eau peut
ne pas savoir si le texte est fini ou pas (il ne suffit pas de
compter les crochets et accolades). À part les objets, les tableaux
et les chaînes de caractères, un texte JSON peut être un nombre, ou
bien un littéral,
Et quel
Lorsqu'on envoie du JSON par le réseau, le
Autre problème classique d'Unicode, la comparaison de chaînes de
caractères. Ces comparaisons doivent se faire selon les caractères
Unicode et pas selon les octets (il y a plusieurs façons de
représenter la même chaîne de caractères, par exemple
JSON est donc un format simple, il n'a même pas la possibilité de commentaires dans le fichier... Voir sur ce sujet une intéressante compilation.
Le premier RFC décrivant JSON était le
Voici un exemple d'un programme
import json
objekt = {u'Image': {u'Width': 800,
u'Title': u'View from Smith\'s, 15th Floor, "Nice"',
u'Thumbnail': {u'Url':
u'http://www.example.com/image/481989943',
u'Width': u'100', u'Height': 125},
u'IDs': [116, 943, 234, 38793],
u'Height': 600}} # Example from RFC 4627, lightly modified
print(json.dumps(objekt))
Et un programme pour lire du JSON et le charger dans un objet Python :
import json
# One backslash for Python, one for JSON
objekt = json.loads("""
{
"Image": {
"Width": 800,
"Height": 600,
"Title": "View from Smith's, 15th Floor, \\\"Nice\\\"",
"Thumbnail": {
"Url": "http://www.example.com/image/481989943",
"Height": 125,
"Width": "100"
},
"IDs": [116, 943, 234, 38793]
}
}
""") # Example from RFC 4267, lightly modified
print(objekt)
print("")
print(objekt["Image"]["Title"])
Le code ci-dessus est très simple car Python (comme
Pour
import org.json.simple.*;
...
Object obj=JSONValue.parse(args[0]);
if (obj == null) { // May be use JSONParser instead, it raises an exception when there is a problem
System.err.println("Invalid JSON text");
System.exit(1);
} else {
System.out.println(obj);
}
JSONObject obj2=(JSONObject)obj; // java.lang.ClassCastException if not a JSON object
System.out.println(obj2.get("foo")); // Displays member named "foo"
Et le produire :
JSONObject obj3=new JSONObject();
obj3.put("name","foo");
obj3.put("num",new Integer(100));
obj3.put("balance",new Double(1000.21));
obj3.put("is_vip",new Boolean(true));
Voyons maintenant des exemples réels avec divers outils de
traitement de JSON. D'abord, les données issues du service de
(v .: "values")
data Station =
Station {stands :: Integer,
bikes :: Integer,
available :: Integer} deriving Show
data Values = Values [Station]
]]>
Mais ça ne marche pas : les nombres dans le fichier JSON ont été
représentés comme des chaînes de caractères ! (Cela illustre un
problème fréquent dans le monde de JSON et de
l'
data Station =
Station {stands :: String,
bikes :: String,
available :: String} deriving Show
Autre problème, les données contiennent parfois la chaîne de
caractères
sumArray a =
show (foldl (+) 0 (map Main.toInteger (filter (\i -> i /= "None") a)))
Le programme
complet est
% curl -s https://download.data.grandlyon.com/ws/rdata/jcd_jcdecaux.jcdvelov/all.json | ./velov
"Stands: 6773"
"Bikes: 2838"
"Available: 3653"
Je n'ai pas utilisé les dates contenues dans ce fichier mais on
peut noter que, si elles sont exprimées en
Un autre exemple de mauvais fichier JSON est donné par
Voyons maintenant un traitement avec le programme spécialisé
dans JSON, jq. On va servir du service de
tests
% curl -s https://tls.imirhil.fr/https/www.bortzmeyer.org.json| jq '.date'
"2017-07-23T14:10:25.760Z"
Notons qu'au moins une clé d'un objet JSON n'est pas nommée
uniquement avec des lettres et chiffres, la clé
, line 1:
._id.$oid
jq: 1 compile error
]]>
Il faut mettre cette clé entre guillemets :
Toujours avec jq, les données de la
% jq '.features | map(select(.properties.geographicalName == "Regensburg Hbf"))' railwayStationNodes.geojson
[
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
12.09966625451,
49.011754555481
]
},
"properties": {
"id": "SNode-1492185",
"formOfNode": "railwayStop",
"railwayStationCode": "NRH",
"geographicalName": "Regensburg Hbf",
...
Toujours avec jq, on peut s'intéresser aux données officielles
états-uniennes en
% jq .data la-crime.json
error: cannot allocate memory
Beaucoup de programmes qui traitent le JSON ont ce problème (un
script Python produit un
Si vous voulez voir un vrai exemple en
% jq '.features | map(select(.properties.nom_de_la_commune == "LE TRAIT"))' laposte_hexasmal.geojson
[
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
0.820017087099,
49.4836816397
]
},
"properties": {
"nom_de_la_commune": "LE TRAIT",
"libell_d_acheminement": "LE TRAIT",
"code_postal": "76580",
"coordonnees_gps": [
49.4836816397,
0.820017087099
],
"code_commune_insee": "76709"
}
}
]
J'avais promis plus haut un exemple écrit en
% ./read-ratp < positions-geographiques-des-stations-du-reseau-ratp.json
26560 stations
Achères-Ville
Alésia
Concorde
...
Comme déjà indiqué, c'est plus délicat en Go que dans un langage
très dynamique comme Python. Il faut construire à l'avance des
structures de données :
type StationFields struct {
Fields Station
}
type Station struct {
Stop_Id int
Stop_Name string
}
Et toute violation du « schéma » des données
par le fichier JSON (quelque chose qui arrive souvent dans la
nature) plantera le programme.
Si on veut beaucoup de fichiers JSON, le service de données
ouvertes officielles
On peut aussi traiter du JSON dans
CREATE TABLE centers (
ID serial NOT NULL PRIMARY KEY,
info json NOT NULL
);
Si
on importe le fichier JSON bêtement dans PostgreSQL (
% jq --compact-output '.features | .[]' centro-salud.json | psql -c "copy centers(info) from stdin" mydb
COPY 50
On peut alors faire des requêtes dans le JSON, avec l'opérateur
mydb=> SELECT info->'properties'->'nombre' AS Nom FROM centers;
nom
------------------------------------------
"P.S. ARABATE"
"INSTITUTO PSICOPEDAGOGICO"
"HOSPITAL GINECO OBSTETRICO"
"HOSPITAL GASTROENTEROLOGICO"
"C.S. VILLA ROSARIO EL TEJAR"
"C.S. BARRIO JAPON"
"C.S. SAN ANTONIO ALTO (CHQ)"
"C.S. SAN JOSE (CHQ)"
"C.S. SAN ROQUE"
...
Bon, sinon, JSON dispose d'une page Web officielle, où vous trouverez plein d'informations. Pour tester dynamiquement vos textes JSON, il y a ce service.