Skip to content

Les fichiers XML sont des arbres sans fleur ni fruit — N°4a/XXX

05/01/2010

Je ne peux pas continuer au-delà sans vous expliquer un peu ce qu’un fichier XML représente pour un processeur XSLT (celui qui va transformer le fichier XML, selon votre préférence, en fichier HTML ou en grenouille).

Fichier XML : description barbare et description « réelle »

Je suis obligé de prendre un fichier légèrement plus complexe (et plus lourd à charger) pour illustrer mon propos, toujours autour des stats de la DLL.

Voici un fichier qui fournit les informations suivantes : pour chaque ville on indique la population et le nombre d’inscrits pour 2005 et 2008.

  • On a toujours un ensemble de notices encadrées par une balise <ville>, qui contient le nom de la ville comme attribut "nom"
  • De cette balise <ville> dépendent systématiquement 2 balises :
    • <an2005>
    • <an2008>
  • Et des balises <an2005> et <an2008> dépendent deux balises :
    • <population>
    • <inscrits>

Par exemple voici les trois premières communes mentionnées dans le fichier XML en question.

Pour l’ignare que vous n’êtes pas,

  • un fichier XML est un fichier texte avec une succession de balises ouvrantes et fermantes, avec du texte au milieu. Et c’est mieux quand à chaque balise ouvrante correspond une balise fermante.
  • On y trouve une balise <dll>, puis une succession de balise <ville>, <an2005>, <an2008>, <population>, <inscrits> et une balise fermante </dll>.
  • Les balises <population> et <inscrits> sont encadrées par les balises <an2005> et </an2005>.
  • Et on pourrait dire qu’Ambérieu-en-Bugey est au-dessus (ou avant) Bellegarde-sur-Valserine.

Mais en fait le processeur XSL voit les choses ainsi

Le processeur XSL descend progressivement dans le fichier, chaque imbrication de balise constituant une nouvelle étape.

  • De la racine / dépend une balise <dll>
  • De <dll> dépendent n balises <ville>
  • De chaque balise <ville> dépend 2 balises
  • etc.

Désignation d’un emplacement dans le fichier XSL

Lorsque j’écris dans le fichier XSL :
<xsl:template match="/">
je me place à la racine de l’arbre.

Lorsque dans ce même fichier j’écris :
<xsl:for-each select="//ville">
C’est que je vais écrire une commande qui va s’appliquer à toutes les balises <ville> — à tous les noeuds <ville>

Les fichiers XML : des noeuds à problèmes

Pour le processeur XSL, chaque subdivision est un nouveau noeud. Il y a trois types de noeuds :

  • noeud element (= balise)
  • noeud text ( =contenu de la balise)
  • noeud attribute (= attribut d’une balise)
    • si la balise contient un attribut, de cette balise dépend un noeud de type attribut
    • et cet attribut aura un noeud de type texte : la valeur de l’attribut.

Cela explique notamment pourquoi ça pose de vrais problèmes au processeur XSL lorsqu’on écrit un fichier XML dont une des balises n’est pas fermée : l’arbre est déraciné

Dans la copie d’écran ci-dessus, on voit un fichier XML qui a un noeud racine : <dll>

  • Ce noeud <dll> (type element) a n nœuds enfants, qui sont n noeuds de type element et de valeur ville (ici, on ne connaît pas le nombre de noeuds mais on pourrait les compter avec la fonction count(//ville))

Chacune de ces <ville> a

  • un noeud de type  attribute, de nom "nom" et de valeur le nom de la ville : <ville nom="Ambérieu">
  • deux noeuds element : <an2005> et <an2008>
  • pas de noeud text (aucun texte ne dépend directement de la balise <ville>)

Et pour chaque noeud enfant de ville :

  • Le noeud attribut "nom" a un noeud enfant de type text : c’est la valeur de l’attribut
  • Chaque noeud <an2005> et <an2008> a deux noeuds element : <population> et <inscrits>.
  • Ces deux noeuds, <population> et <inscrits> ont chacun un noeud enfant de type text.

Application dans un fichier XSL

  • Chaque fois que je descend d’un niveau dans l’arbre, je rajoute un slash /, puis je mets le nom du noeud (exactement comme pour descendre dans une arborescence de dossiers sur un ordinateur).
    • Le double-slash // permet de dire : un noeud, n’importe où dans l’arbre.
  • Si c’est un noeud de type attribute qui m’intéresse, je rajouterai un @ devant le nom.

Par exemple, si je me place au niveau de chaque ville, et que je veux récupérer

  • le nom de la ville (attribut "nom" de la balise <ville>)
  • et la valeur de la population en 2005
<xsl:for-each select= »//ville »> Avec la balise for-each, je me place dans l’arborescence au niveau de chacun des noeuds <ville>.

Tout ce qui sera compris entre les balises <xsl:for-each select= »//ville »> et </xsl:for-each> positionne le processeur à ce niveau-là

<xsl:text>Nom de la ville : </xsl:text><xsl:value-of select= »@nom »/> On désigne un noeud attribute de <ville>, pour en récupérer la valeur.

Le processeur cherche donc un noeud enfant dépendant immédiatement de <ville> (un attribut de <ville>, donc)

Attention : il ne faut pas écrire : select="/@nom", mais bien select="@nom" pour descendre d’un niveau dans l’arborescence

<xsl:text>Population en 2005 : </xsl:text><xsl:value-of select="an2005/population"/> Ensuite, on demande au processeur XSLT de chercher un noeud enfant de type element et de nom "an2005" (on cherche une balise <an2005> dépendant immédiatement de <ville>

Et sous cet element on cherche un autre element <population>, dont on récupère la valeur.

</xsl:for-each> Fin de la boucle "for-each"
Advertisements
%d blogueurs aiment cette page :