Encodage d'objets complexes

De knowledge
Aller à la navigation Aller à la recherche

Il y a beaucoup de méthodes pour encoder les objets complexes. La méthode de base consiste en les "sérialiser" ou les transformer en une suite d'octets par exemple, de caractères ASCII ou autre.

XML ou Extensible Markup Language

L'un des premier format utilisé des les années 90. Son format de balise a été popularisé par HTML qui peut être vu comme une implémentation de XML pour dessiner des pages web.

A la base c'est un document texte dont les objets sont définis pas des tags entourant un contenu :

<planete>Terre</planete>

On définie la terre. On peut lui ajouter des attributs :

<planete ordre="3">Terre</planete>

La terre est la troisième planète en partant du soleil. So on veut définir le système solaire:

<systeme galaxie="voie lactee" etoile="soleil">
  <planete ordre="1">Mercure</planete>
  <planete ordre="2">Venus</planete>
  <planete ordre="3">Terre</planete>
  <planete ordre="4">Mars</planete>
  <planete ordre="5">Jupiter</planete>
  <planete ordre="5">Saturne</planete>
  <planete ordre="6">Uranus</planete>
  <planete ordre="7">Neptune</planete>
</systeme>

Oui Pluton n'est plus une planète depuis 2006!

On remarque que les espaces les tabulations et les retour chariots sont tous considérés comme des séparateurs. n séparateurs sont considérés comme un séparateur.

On doit également ajouter une en-tête pour définir, à minima, la version de XML, le jeu de caractère utilisé et si la suite doit être interprétée avec un DTD ou pas. Un DTD est un document (aussi en XML) décrivant la structure de l'objet (a grammaire).

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

C'est le plus simple.

JSON ou JavaScript Object Notation

Avec l'essor de JavaScript côté client depuis des décennies et côté serveur depuis un peu mois, le format des objet au format javascript en tant que chaine de caractères est apparu comme un bon mécanisme d'échange.

L'objet ci dessus ressemblerait donc à :

{
	"systeme": {
		"planete": [
			{
				"ordre": 1,
				"name": "Mercure"
			},
			{
				"ordre": 2,
				"name": "Venus"
			},
			{
				"ordre": 3,
				"name": "Terre"
			},
			{
				"ordre": 4,
				"name": "Mars"
			},
			{
				"ordre": 5,
				"name": "Jupiter"
			},
			{
				"ordre": 6,
				"name": "Saturne"
			},
			{
				"ordre": 7,
				"name": "Uranus"
			},
			{
				"ordre": 8,
				"name": "Neptune"
			}
		],
		"galaxie": "voie lactee",
		"etoile": "soleil"
	}
}

Usage en Javascript

En javascript il y a une commande eval qui prends en paramètre une chaine de caractères et retourne l'objet correspondant.

// Un objet JSON
text='{"name": "saturne", "order":6 }'
// on l'évalue pour en faire un objet
obj=eval('('+text+')');
// On imprime le texte de l'objet
console.log(text);
// on imprime l'objet 
console.log(obj);
// On accede aux données membres
console.log(obj.name);
console.log(obj.order);

La sortie sur la console donne :

{"name": "saturne", "order":6 }
{ name: 'saturne', order: 6 }
saturne
6

Usage en shell (commande jq)

Parcours simple (un champ et toutes les lignes)

cat planetes.json | jq '.systeme.galaxie'

nous donne :

"voie lactee"

pour avoir la liste des noms de planètes

cat planetes.json | jq '.systeme.planete[].name'

Rends bien

"Mercure"
"Venus"
"Terre"
"Mars"
"Jupiter"
"Saturne"
"Uranus"
"Neptune"

Sélection de plusieurs champs

On a une structure un peu plus complète :

{
        "systeme": {
                "planete": [
                        {
                                "ordre": 1,
                                "name": "Mercure",
                                "size": 4879.4
                        },
                        {
                                "ordre": 2,
                                "name": "Venus",
                                "size": 12104.0
                        },
....
                ],
                "galaxie": "voie lactee",
                "etoile": "soleil"
        }
}

On ne veut que le nom et la taille des planetes:

jq '.systeme.planete[] | {nom: .name, diametre: .size}' planetes.json

Qui nous réponds:

{
  "nom": "Mercure",
  "diametre": 4879.4
}
{
  "nom": "Venus",
  "diametre": 12104.0
}
{
  "nom": "Terre",
  "diametre": 12756.0
}
{
  "nom": "Mars",
  "diametre": 6779.0
}
{
  "nom": "Jupiter",
  "diametre": 139820.0
}
{
  "nom": "Saturne",
  "diametre": 116460.0
}
{
  "nom": "Uranus",
  "diametre": 50724.0
}
{
  "nom": "Neptune",
  "diametre": 49244.0
}

Ajout d'une condition

jq '.systeme.planete[] | {nom: .name, diametre: .size} | select(.nom=="Terre")' planetes.json

Qui nous donne les infos pour la Terre:

{
  "nom": "Terre",
  "diametre": 12756.0
}

et:

jq '.systeme.planete[] | {nom: .name, diametre: .size} | select(.diametre < 30000.0)' planetes.json

Nous donne la liste des planètes dont le diamètre est inférieur à 30 000km

{
  "nom": "Mercure",
  "diametre": 4879.4
}
{
  "nom": "Venus",
  "diametre": 12104.0
}
{
  "nom": "Terre",
  "diametre": 12756.0
}
{
  "nom": "Mars",
  "diametre": 6779.0
}

On sait faire des select et des where comme SQL. En revanche le mot clé pour la clause where c'est... SELECT.