20 novembre 2007

Le bon et le mauvais XML (suite)

Bis repetita...

Cela fait plusieurs fois que je donne mon avis sur ce sujet, et déjà il y a quelques temps, partiellement, sur ce blog. Voici donc dans le détail un peu d'explication sur les "profondeurs de XML"...

Je reçois ce jour la question d'un collègue et ami :

Si fonctionnellement on a ça :


Alors techniquement on peut avoir ça :


Et donc en XML l'adresse est "imbriquée" :

Est-ce correct ? La recopie avec des imbrications à " l'infini " pose problème, ne serait-ce que la lisibilité du fichier XML, non ?

Ma réponse :
En Java (par exemple) la classe sera définie avec une référence à Adresse :
public class Personne {
private Civilite civilite;
private String nom;
private String prenom;
private Adresse adresse; // <- ceci est une référence vers une adresse (ie: l'objet n'est pas dans la classe personne)
}

On aura d'ailleurs :
public class Adresse {
private String num;
private String voie;
// etc.
}

En XML la notion de référence n'est pas native, ce qui fait qu'on a parfois l'impression (seulement l'impression) qu'on doit imbriquer les niveaux :

Ce XML est valide et utilisable dans un message, oui mais...

Les inconvénients d'une telle pratique sont :
1) Jusqu'où aller ? quelle profondeur notre arbre aura au final ? (ie : message.contrat.contractant.personne.adresse.voie. ... , on peut parfois aller loin comme ça !)
2) Comment référencer la même adresse sans la recopier ?
3) comment avoir la même souplesse qu'en Java : une simple référence vers un objet Adresse depuis un objet Personne qui reste simple ?

Il a donc été créé en XML la notion de référence (id/idref ou key/keyref).
Donc la bonne idée est la suivante :


On est toujours en XML valide (penser à englober les 2 éléments dans un élement de plus haut niveau, par exemple
). C'est un mécanisme standard et conseillé mais peu usité car les développeurs ont tendance à préférer des formats très arborescents, ce qui est une erreur pour la lisibilité et l'évolutivité des messages.

Subsiste alors une question : id/idref ou key/keyref ?
La différence :
Dans id/idref , id est un identifiant local au message (ex: "adresse1"), qui n'a aucun sens en dehors du message.
Dans key/keyref, key est une clef externe au message (ie: numéro de compte client, identifiant de contrat, etc.).
La question du choix entre id et key est très importante, et il convient de n'accorder
aucun crédit aux réponses absolues du type "toujours key/keyref" (source: O'Reilly). Il faut, selon le cas, choisir l'un ou l'autre.

Guidelines :
-> Utiliser key/keyref c'est se donner l'avantage de la cohérence (en cas d'incohérence une simple requête au référentiel suffira à retrouver l'information). Typiquement : un n° de contrat, un n° de client, un id de transaction, un code pays.
-> Utiliser id/idref c'est garantir qu'on limitera les niveaux d'arborescence (= garantir l'évolutivité et la lisibilité [par le logiciel] des messages), même si les objets référencés n'ont pas d'identifiant unique déclaré. Cette technique est typiquement utilisée pour des objets plus volatiles : une adresse ou tout type de coordonnées, le résultat d'un calcul ou d'un contrôle, etc.

Pour aller encore plus loin :
On suggère de réifier chaque relation (ie: la flèche, dans le diagramme UML, devient un objet XML, du type , et qui peut utiliser des id/idref), afin d'être encore plus évolutif.

Parfois plus difficile à construire, mais tellement plus viable !

On peut aussi utiliser xlink, etc.

Autrement dit, le champ des possibles est vaste, mais on peut commencer par privilégier id/idref ou key/keyref.

1 commentaire:

ghislain a dit…

Très bon point qu'on omet souvent lors de la conception des fichiers xml. J'en tiendrai compte dans mes prochains modèles.