TP 4
TP 4
TP 4
XML
(1) Le fichier films.xml comportera l’élément racine BibFilm et son élément enfant film.
(3) A l’aide de ces balises, insérer les données existant dans le fichier BaseDonneesFilms.txt qui
contient les données des 9 films.
DTD
(1) Associez à films.xml une DTD externe (TestFilm.dtd) pour que films.xml soit Valide.
(2) Mettez les règles nécessaires que doit satisfaire films.xml dans le fichier TestFilm.dtd.
CSS
Composez un fichier CSS qui permet d’afficher les films.
Améliorez le CSS comme dans les exemples du Cours.
XSD
On crée un fichier nommé films.xsl qu’on associe à fims.xsl. Pensez à dissocier TestFilm.dtd de
fims.xsl.
(1) Créez un fichier films.xsd et associez le au fichier films.xml.
(2) Définissez les éléments utilisés dans films.xml en leur donnant le type adéquat.
(3) On impose que tous les films de films.xml doivent être sortis après l’an 1900.
(6) Insérer des dates de naissances pour tous les réalisateurs, et deux dates de décès pour deux
réalisateurs au choix.
XSL
On crée un fichier nommé films.xsl qu’on associe à fims.xsl. Pensez à dissocier le fichier css de
fims.xsl.
voir l’image de l’exécution en bas.
(1) Dans la balise <title></title>, on met le titre du document Films.
– On fusionne les cellules de la première ligne et on y met le titre du film (alignement centré).
– Ligne 2 : dans la cellule 1 on met "Film réalisé par :" (alignement à droite). Dans la cellule 2
(alignement à gauche), on met NomRealisateur né en AnneeNaissance, et s’il est mort on
rajoute, décédé en AnneeDeces. Retour à la ligne. On affiche les réalisateurs par ordre
alphabétique.
– Ligne 3 : dans la cellule 1 on met "Acteurs :" (alignement à droite). Dans la cellule 2 (alignement
à gauche), on met NomActeur. Retour à la ligne. On affiche les acteurs par ordre alphabétique.
On refait la même chose avec pays.
– Ligne 5 : dans la cellule 1 on met "Année de sortie :" (alignement à droite). Dans la cellule 2
– Ligne 6 : dans la cellule 1 on met "Durée :" (alignement à droite). Dans la cellule 2 (alignement à
gauche), on met DureeFilm.
Partie XSLT - Transformation
Commencez avec un document XML brut
Nous voulons transformer le document XML suivant ("cdcatalog.xml") en XHTML:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Lier la feuille de style XSL au document XML
Ajoutez la référence de feuille de style XSL à votre document XML ("cdcatalog.xml"):
L'attribut match est utilisé pour associer un modèle à un élément XML. L'attribut match peut
également être utilisé pour définir un modèle pour l'ensemble du document XML. La valeur de
l'attribut match est une expression XPath (c'est-à-dire que match = "/" définit l'ensemble du
document).
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<tr>
<td>.</td>
<td>.</td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
RESULTAT
XSLT <xsl:value-of> Element
L'élément <xsl: value-of> peut être utilisé pour extraire la
valeur d'un élément XML et l'ajouter au flux de sortie de la
transformation:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<tr>
<td><xsl:value-of select="catalog/cd/title"/></td>
<td><xsl:value-of select="catalog/cd/artist"/></td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
l'attribut select, dans l'exemple ci-dessus, contient une expression XPath. Une expression XPath
fonctionne comme la navigation dans un système de fichiers; une barre oblique (/) sélectionne les
sous-répertoires.
Le résultat de l'exemple ci-dessus était un peu décevant; une seule ligne de données a été copiée du
document XML vers la sortie. Dans le chapitre suivant, vous apprendrez à utiliser l'élément <xsl:
foreach> pour parcourir les éléments XML et afficher tous les enregistrements.
</xsl:stylesheet>
Resulattt
Filtrer la sortie
Nous pouvons également filtrer la sortie du fichier XML en ajoutant un critère à l'attribut select dans
l'élément <xsl: for-each>.
= (equal)
• != (not equal)
• < less than
• > greater than
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd[artist='Bob Dylan']">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Resultat
XSLT <xsl:sort> Element
Où mettre les informations de tri
Pour trier la sortie, ajoutez simplement un élément <xsl: sort> à l'intérieur de l'élément <xsl:
foreach> dans le fichier XSL:
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<xsl:sort select="artist"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Resultat
XSLT <xsl:if> Element
Pour placer un test if conditionnel par rapport au contenu du fichier XML, ajoutez un élément <xsl:
if> au document XSL.
<xsl:if test="expression">
... une sortie si l'expression est vraie... </xsl:if>
Où placer l'élément <xsl: if>
Pour ajouter un test conditionnel, ajoutez l'élément <xsl: if> à l'intérieur de l'élément <xsl: for-each>
dans le fichier XSL:
<xsl:choose>
<xsl:when test="expression">
... some output ...
</xsl:when>
<xsl:otherwise>
... some output ....
</xsl:otherwise> </xsl:choose>
Où mettre la condition de choix
Pour insérer un test conditionnel multiple par rapport au fichier XML, ajoutez les éléments <xsl:
choose>, <xsl: when> et <xsl: else> au fichier XSL:
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<xsl:choose>
<xsl:when test="price > 10">
<td bgcolor="#ff00ff">
<xsl:value-of select="artist"/></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="artist"/></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Un autre exemple
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<xsl:choose>
<xsl:when test="price > 10">
<td bgcolor="#ff00ff">
<xsl:value-of select="artist"/></td>
</xsl:when>
<xsl:when test="price > 9">
<td bgcolor="#cccccc">
<xsl:value-of select="artist"/></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="artist"/></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Si nous ajoutons un attribut "select" à l'élément <xsl: apply-templates>, il ne traitera que les
éléments enfants qui correspondent à la valeur de l'attribut. Nous pouvons utiliser l'attribut "select"
pour spécifier dans quel ordre les nœuds enfants doivent être traités.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="cd">
<p>
<xsl:apply-templates select="title"/>
<xsl:apply-templates select="artist"/>
</p>
</xsl:template>
<xsl:template match="title">
Title: <span style="color:#ff0000">
<xsl:value-of select="."/></span>
<br />
</xsl:template>
<xsl:template match="artist">
Artist: <span style="color:#00ff00">
<xsl:value-of select="."/></span>
<br />
</xsl:template>
</xsl:stylesheet>
XSLT - Sur le client
Une solution JavaScript
Dans les chapitres précédents, nous avons expliqué comment XSLT peut être utilisé pour transformer
un document XML en XHTML. Nous l'avons fait en ajoutant une feuille de style XSL au fichier XML et
en laissant le navigateur faire la transformation.
Même si cela fonctionne correctement, il n'est pas toujours souhaitable d'inclure une référence de
feuille de style dans un fichier XML (par exemple, cela ne fonctionnera pas dans un navigateur non
compatible XSLT.)
Une solution plus polyvalente consisterait à utiliser un JavaScript pour effectuer la transformation.
<!DOCTYPE html>
<html>
<head> <script>
function loadXMLDoc(filename)
{
if (window.ActiveXObject)
{
xhttp = new ActiveXObject("Msxml2.XMLHTTP");
} else
{
xhttp = new XMLHttpRequest();
}
xhttp.open("GET", filename, false);
try {xhttp.responseType = "msxml-document"} catch(err) {} // Helping IE11 xhttp.send("");
return xhttp.responseXML;
}
function displayResult()
{
xml = loadXMLDoc("cdcatalog.xml"); xsl
= loadXMLDoc("cdcatalog.xsl");
// code for IE
if (window.ActiveXObject || xhttp.responseType == "msxml-document")
{
ex = xml.transformNode(xsl);
document.getElementById("example").innerHTML = ex;
}
// code for Chrome, Firefox, Opera, etc.
else if (document.implementation && document.implementation.createDocument)
{
xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl); resultDocument =
xsltProcessor.transformToFragment(xml, document);
document.getElementById("example").appendChild(resultDocument);
}
}
</script>
</head>
<body onload="displayResult()">
<div id="example" />
</body>
</html>
Exemple explication:
La fonction loadXMLDoc () effectue les opérations suivantes:
La fonction displayResult () est utilisée pour afficher le fichier XML stylisé par le fichier XSL:
Voici le code source PHP nécessaire pour transformer le fichier XML en XHTML sur le serveur
<?php
// Load XML file
$xml = new DOMDocument;
$xml->load('cdcatalog.xml');
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>
Le document XML ci-dessus se compose d'un élément racine, "shiporder", qui contient un attribut
obligatoire appelé "orderid". L'élément "shiporder" contient trois éléments enfants différents :
"orderperson", "shipto" et "item". L'élément "item" apparaît deux fois et contient un élément "title",
un élément facultatif "note", un élément "quantity" et un élément "price".
Nous commençons par ouvrir un nouveau fichier que nous appellerons "shiporder.xsd". Pour créer le
schéma, nous pourrions simplement suivre la structure du document XML et définir chaque élément
tel que nous le trouvons. Nous commencerons par la déclaration XML standard suivie de l'élément
xs:schema qui définit un schéma :
Dans le schéma ci-dessus, nous utilisons l'espace de noms standard (xs), et l'URI associé à cet espace
de noms est la définition du langage Schema, qui a la valeur standard de
http://www.w3.org/2001/XMLSchema.
Ensuite, nous devons définir l'élément "shiporder". Cet élément a un attribut et il contient d'autres
éléments, nous le considérons donc comme un type complexe. Les éléments enfants de l'élément
"shiporder" sont entourés d'un élément xs:sequence qui définit une séquence ordonnée de sous-
éléments :
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
</xs:element>
Ensuite, nous devons définir l'élément "orderperson" comme un type simple (car il ne contient aucun
attribut ou autre élément). Le type (xs:string) est précédé du préfixe d'espace de noms associé au
schéma XML qui indique un type de données de schéma prédéfini :
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Avec les schémas, nous pouvons définir le nombre d'occurrences possibles pour un élément avec les
attributs maxOccurs et minOccurs. maxOccurs spécifie le nombre maximum d'occurrences pour un
élément et minOccurs spécifie le nombre minimum d'occurrences pour un élément. La valeur par
défaut pour maxOccurs et minOccurs est 1 !
Nous pouvons maintenant définir l'élément "item". Cet élément peut apparaître plusieurs fois dans un
élément "shiporder". Ceci est spécifié en définissant l'attribut maxOccurs de l'élément "item" sur
"unbounded", ce qui signifie qu'il peut y avoir autant d'occurrences de l'élément "item" que l'auteur le
souhaite. Notez que l'élément "note" est facultatif. Nous l'avons spécifié en définissant l'attribut
minOccurs sur zéro :
Nous pouvons maintenant déclarer l'attribut de l'élément "shiporder". Puisqu'il s'agit d'un attribut
obligatoire, nous spécifions use="required".
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
Diviser le schéma
La méthode de conception précédente est très simple, mais peut être difficile à lire et à maintenir
lorsque les documents sont complexes.
La méthode de conception suivante consiste à définir d'abord tous les éléments et attributs, puis à s'y
référer à l'aide de l'attribut ref.
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
La troisième méthode de conception définit des classes ou des types, ce qui nous permet de réutiliser
les définitions d'éléments. Cela se fait en nommant les éléments simpleTypes et complexTypes, puis
en pointant vers eux via l'attribut type de l'élément.
<xs:simpleType name="stringtype">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="inttype">
<xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>
<xs:simpleType name="dectype">
<xs:restriction base="xs:decimal"/>
</xs:simpleType>
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="shiptotype">
<xs:sequence>
<xs:element name="name" type="stringtype"/>
<xs:element name="address" type="stringtype"/>
<xs:element name="city" type="stringtype"/>
<xs:element name="country" type="stringtype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemtype">
<xs:sequence>
<xs:element name="title" type="stringtype"/>
<xs:element name="note" type="stringtype" minOccurs="0"/>
<xs:element name="quantity" type="inttype"/>
<xs:element name="price" type="dectype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="shipordertype">
<xs:sequence>
<xs:element name="orderperson" type="stringtype"/>
<xs:element name="shipto" type="shiptotype"/>
<xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
</xs:sequence>
<xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>
</xs:schema>
L'élément de restriction indique que le type de données est dérivé d'un type de données d'espace de
noms W3C XML Schema. Ainsi, le fragment suivant signifie que la valeur de l'élément ou de l'attribut
doit être une valeur de chaîne :
<xs:restriction base="xs:string">
L'élément de restriction est plus souvent utilisé pour appliquer des restrictions aux éléments. Regardez
les lignes suivantes du schéma ci-dessus :
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
Cela indique que la valeur de l'élément ou de l'attribut doit être une chaîne, qu'elle doit contenir
exactement six caractères d'affilée et que ces caractères doivent être un nombre compris entre 0 et 9.