Link Search Menu Expand Document

Schéma XML - les types complexes

Dans les chapitres précédents, nous avons vu les éléments simples et les différentes familles de types simples. Malheureusement, toutes ces connaissances ne sont pas suffisantes si l’on souhaite pouvoir décrire toutes les structures que les documents XML offrent.

Pour pallier ce manque, nous allons maintenant aborder la suite du cours via l’étude d’un nouveau type d’élément : les éléments complexes.

Définition

Bref rappel

Au cours des chapitres précédents, nous avons vu ensemble ce qu’est un élément simple, à savoir un élément qui ne contient qu’une valeur dont le type est dit simple. Un élément simple ne contient pas d’autres éléments ni aucun attribut.

Nous avons également vu comment déclarer un élément simple ainsi qu’un attribut. Cependant nous n’avons pas vu comment déclarer un attribut dans un élément. En effet, un élément qui possède un attribut n’est plus un élément simple. On parle alors d’élément complexe.

Les éléments complexes

Un élément complexe est un élément qui contient d’autres éléments ou des attributs. Bien évidemment les éléments contenus dans un élément peuvent également contenir des éléments ou des attributs. J’espère que vous suivez toujours ! 😉

Je vous propose de voir quelques exemples d’éléments XML qui dans un Schéma XML sont considérés comme complexes :

<!-- la balise personne contient d'autres balises => élément complexe -->
<personne>
  <!-- la balise nom est un élément simple -->
  <nom>ROBERT</nom>
  <!-- la balise prenom est un élément simple -->
  <prenom>Axel</prenom>
</personne>

<!-- la balise personne possède un attribut => élément complexe -->
<personne sexe="feminin">Axel ROBERT</personne>

Abordons maintenant différents exemples qui vont nous permettre de voir et de comprendre comment déclarer des éléments complexes dans un Schéma XML.

Déclarer un élément complexe

Si vous souhaitez déclarer une balise en tant qu’élément complexe, c’est le mot clef complexType qu’il faut utiliser associé à celui que nous connaissons déjà : element. N’oubliez pas de précéder son utilisation par xsd:

<xsd:element name="mon_nom">
  <xsd:complexType>
    <!-- contenu ici -->
  </xsd:complexType>
</xsd:element>

Nous reviendrons juste après sur la notion de contenu, ne vous inquiétez pas. 😉

Reprenons l’un des éléments de type complexe que nous avons vu un peu plus haut :

<personne>
  <nom>ROBERT</nom>
  <prenom>Axel</prenom>
</personne>

Voici comment le déclarer :

<xsd:element name="personne">
  <xsd:complexType>
    <!-- contenu ici -->
  </xsd:complexType>
</xsd:element>

Les contenus des types complexes

Concernant les types complexes, il est important de noter qu’il existe 3 types de contenus possibles :

  • Les contenus simples.
  • Les contenus “standards”.
  • Les contenus mixtes.

Les contenus simples

Définition

Le premier type de contenu possible pour un élément complexe est le contenu simple.

On appelle contenu simple, le contenu d’un élément complexe qui n’est composé que d’attributs et d’un texte de type simple.

Quelques exemples

Je vous propose de voir quelques exemples d’éléments complexes dont le contenu est dit simple.

<!-- contient un attribut et du texte -->
<prix devise="euros">35</prix>

<!-- contient un attribut et du texte -->
<voiture marque="Renault">Clio</voiture>

Du côté du Schéma XML

La syntaxe

Pour déclarer un élément complexe faisant référence à une balise contenant des attributs et du texte, voici la syntaxe à utiliser :

<xsd:element name="mon_nom">
  <xsd:complexType>
    <xsd:simpleContent>
      <xsd:extension base="mon_type">
        <xsd:attribute name="mon_nom" type="mon_type"/>
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>
</xsd:element>

Un exemple

Reprenons l’exemple d’un prix prenant pour attribut une devise :

<prix devise="euros">35</prix>

Voici alors le schéma XML associé :

<xsd:element name="prix">
  <xsd:complexType>
    <xsd:simpleContent>
      <xsd:extension base="xsd:positiveInteger">
        <xsd:attribute name="devise" type="xsd:string"/>
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>
</xsd:element>

Dans le cas où la balise que l’on cherche à décrire contient plusieurs attributs, il convient de tout simplement les lister entre les balises <xsd:extension />. Par exemple :

<voiture marque="Renault" type="essence">Clio</voiture>
<xsd:element name="voiture">
  <xsd:complexType>
    <xsd:simpleContent>
      <xsd:extension base="xsd:string">
        <xsd:attribute name="marque" type="xsd:string"/>
        <xsd:attribute name="type" type="xsd:string"/>
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>
</xsd:element>

Comme vous pouvez le constater, on se contente de mettre à la suite les différents attributs qui composent l’élément. À noter que l’ordre dans lequel les attributs sont déclarés dans le Schéma XML n’a aucune importance.

Les contenus “standards”

Définition

Après les contenus simples, nous allons monter la barre d’un cran et nous attaquer aux contenus “standards”.

Ce que j’appelle contenu “standard”, c’est le contenu d’un élément complexe qui n’est composé que d’autres éléments (simples ou complexes) ou uniquement d’attributs.

Quelques exemples

Comme pour le contenu simple, voyons quelques exemples de contenu “standard” :

<!-- contient d'autres éléments -->
<personne>
  <nom>DUPONT</nom>
  <prenom>Robert</prenom>
</personne>

<!-- contient un attribut -->
<voiture marque="Renault"/>

Balise contenant un ou plusieurs attributs

Je vous propose de débuter par le cas de figure le plus simple, à savoir celui d’un élément complexe qui ne contient que des attributs.

Reprenons l’exemple de notre voiture du dessus :

<voiture marque="Renault" />

Voici alors le Schéma XML associé :

<xsd:element name="voiture">
  <xsd:complexType>
    <xsd:attribute name="marque" type="xsd:string"/>
  </xsd:complexType>
</xsd:element>

Il n’y a, pour le moment, rien de bien compliqué. On se contente d’imbriquer une balise <xsd:attribute /> dans une balise <xsd:complexType />.

Si l’on tente de complexifier un petit peu les choses, nous allons nous rendre compte que, dans le fond, rien ne change. Prenons par exemple le cas d’une balise contenant plusieurs attributs :

<voiture marque="Renault" modele="Clio" />

Regardons alors le Schéma XML :

<xsd:element name="voiture">
  <xsd:complexType>
    <xsd:attribute name="marque" type="xsd:string" />
    <xsd:attribute name="modele" type="xsd:string" />
  </xsd:complexType>
</xsd:element>

Comme vous pouvez le constater, on se contente de mettre à la suite les différents attributs qui composent l’élément. Une fois de plus, l’ordre dans lequel les balisessont placées n’a aucune importance.

Balise contenant d’autres éléments

Il est maintenant temps de passer à la suite et de jeter un coup d’œil aux balises qui contiennent d’autres éléments.

La séquence

Une séquence est utilisée lorsque l’on souhaite spécifier que les éléments contenus dans un type complexe doivent apparaître dans un ordre précis.

Voici comment se déclare une séquence au niveau d’un Schéma XML :

<xsd:element name="mon_nom">
  <xsd:complexType>
    <xsd:sequence>
      <!-- liste des éléments -->
    </xsd:sequence>
    <!-- listes des attributs -->  
  </xsd:complexType>
</xsd:element>

Voyons tout de suite un exemple :

<xsd:element name="personne">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="nom" type="xsd:string" />
      <xsd:element name="prenom" type="xsd:string" />
    </xsd:sequence>
    <xsd:attribute name="sexe" type="xsd:string" />
  </xsd:complexType>
</xsd:element>

Cet extrait signifie que la balise <personne /> qui possède l’attribut sexe, contient les balises <nom /> et <prenom /> dans cet ordre.

Illustrons alors cet exemple :

<!-- valide -->
<personne sexe="masculin">
  <nom>DUPONT</nom>
  <prenom>Robert</prenom>
</personne>

<!-- invalide => les balises nom et prenom sont inversées -->
<personne sexe="masculin">
  <prenom>Robert</prenom>
  <nom>DUPONT</nom>
</personne>

Le type all

Le type all est utilisé lorsque l’on veut spécifier que les éléments contenus dans un type complexe peuvent apparaître dans n’importe quel ordre. Ils doivent cependant tous apparaître une et une seule fois.

Voici comment se déclare le type all au niveau d’un Schéma XML :

<xsd:element name="mon_nom">
  <xsd:complexType>
    <xsd:all>
      <!-- liste des éléments -->
    </xsd:all>
    <!-- listes des attributs -->
  </xsd:complexType>
</xsd:element>

Voyons tout de suite un exemple :

<xsd:element name="personne">
  <xsd:complexType>
    <xsd:all>
      <xsd:element name="nom" type="xsd:string" />
      <xsd:element name="prenom" type="xsd:string" />
    </xsd:all>
  </xsd:complexType>
</xsd:element>

Cet extrait signifie donc que la balise <personne /> contient les balises <nom /> et <prenom /> dans n’importe quel ordre.

Illustrons alors cet exemple :

<!-- valide -->
<personne sexe="masculin">
  <nom>DUPONT</nom>
  <prenom>Robert</prenom>
</personne>

<!-- valide -->
<personne sexe="masculin">
  <prenom>Robert</prenom>
  <nom>DUPONT</nom>
</personne>

Le choix

Un choix est utilisé lorsque l’on veut spécifier qu’un élément contenu dans un type complexe soit choisi dans une liste pré-définie.

Voici comment se déclare un choix au niveau d’un Schéma XML :

<xsd:element name="mon_nom">
  <xsd:complexType >
    <xsd:choice>
      <!-- liste des éléments -->
    </xsd:choice>
    <!-- listes des attributs -->
  </xsd:complexType>
</xsd:element>

Voyons sans plus tarder un exemple :

<xsd:element name="personne">
  <xsd:complexType>
    <xsd:choice>
      <xsd:element name="nom" type="xsd:string" />
      <xsd:element name="prenom" type="xsd:string" />
    </xsd:choice>
  </xsd:complexType>
</xsd:element>

Cet extrait signifie donc que la balise <personne /> contient soit la balise <nom />, soit <prenom />.

Illustrons cet exemple :

<!-- valide -->
<personne sexe="masculin">
  <nom>DUPONT</nom>
</personne>

<!-- valide -->
<personne sexe="masculin">
  <prenom>Robert</prenom>
</personne>

<!-- invalide => les 2 balises prenom et nom ne peuvent pas apparaître en même temps -->
<personne sexe="masculin">
  <prenom>Robert</prenom>
  <nom>DUPONT</nom>
</personne>

Cas d’un type complexe encapsulant un type complexe

Avant de terminer cette partie, il nous reste un cas à voir : celui d’un type complexe encapsulant également un type complexe.

Prenons par exemple le document XML suivant :

<?xml version="1.0" encoding="UTF-8"?>
<personne>
  <identite>
    <nom>NORRIS</nom>
    <prenom>Chuck</prenom>
  </identite>
</personne>

Ce document XML permet d’identifier une personne via son nom et son prénom. Voyons alors le Schéma XML qui définit notre document XML :

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="personne">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="identite">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="nom" type="xsd:string" />
              <xsd:element name="prenom" type="xsd:string" />
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

En soi, il n’y a rien de compliqué. Il convient juste de repérer que lorsque l’on place un élément complexe au sein d’un autre élément complexe, dans notre cas, une identité dans une personne, il convient d’utiliser une séquence, un choix ou un type all.

Les contenus mixtes

Définition

Il est temps de conclure ce chapitre avec le dernier type de contenu possible : les contenus mixtes.

Un contenu mixte est le contenu d’un élément complexe qui est composé d’attributs, d’éléments et de texte.

Un exemple

Afin d’illustrer cette définition, je vous propose de nous appuyer sur un exemple :

<balise1>
  Ceci est une chaîne de caractères
  <balise2>10</balise2>
  7.5
</balise1>

Du côté du Schéma XML

La syntaxe

Pour déclarer un élément complexe au contenu mixte, voici la syntaxe à utiliser :

<xsd:element name="mon_nom">
  <xsd:complexType  mixed="true">
    <!-- liste des éléments -->
  </xsd:complexType>
  <!-- liste des attributs -->
</xsd:element>

La nouveauté est donc l’utilisation du mot clef mixed.

Un exemple

Prenons l’exemple d’une facture fictive dans laquelle on souhaite identifier l’acheteur et la somme qu’il doit payer.

<facture><acheteur>Zozor</acheteur>, doit payer <somme>1000</somme>€.</facture>

Voici comment le traduire au sein d’un Schéma XML :

<xsd:element name="facture">
  <xsd:complexType mixed="true">
    <xsd:sequence>
      <xsd:element name="acheteur" type="xsd:string" />
      <xsd:element name="somme" type="xsd:int" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

Comme vous pouvez le remarquer, j’ai utilisé la balise <xsd:sequence /> pour encapsuler la liste des balises contenues dans la balise <facture />, mais vous pouvez bien évidemment adapter à votre cas de figure et choisir parmi les balises que nous avons vu dans le chapitre précédent, à savoir :

  • <xsd:sequence />
  • <xsd:all />
  • <xsd:choice />

En résumé

  • Un élément complexe est un élément qui contient d’autres éléments ou des attributs.
  • Un élément complexe est décrit grâce à la balise.
  • Un élément complexe a 3 types de contenus possibles : les contenus simples, “standards” et mixtes.

Ce cours vous plait ?

Retrouvez ce cours en livre physique sur Amazon !