XML en M1 (2018), université d'Angers
gilles.hunault@univ-angers.fr
T.P. numéro 1
Table des matières cliquable
1. Rendre un document HTML valide pour la grammaire XHTML 1.0 Strict
2. Passer de XHTML 1.0 Transitionnel à XHTML 1.0 Strict
3. Créer un document XML qui respecte une grammaire DTD
4. Créer un document XML qui respecte une grammaire XSD
5. Créer des grammaires DTD et XSD
Il est possible d'afficher toutes les solutions via ?solutions=1 et de les masquer via ?solutions=0 .
1. Rendre un document HTML valide pour la grammaire XHTML 1.0 Strict
Ce n'est pas parce qu'un navigateur affiche un document qu'il est valide. Corriger le document HTML de l'archive m1xml_bad.zip pour qu'il soit valide pour la grammaire XHTML 1.0 Strict. On pourra utiliser des outils Web ou en ligne de commande.
Solution : afficher la solution
Que ce soit à l'aide d'un outil Web comme le W3C validator, d'un outil intégré à Firefox comme HTML Validator ou d'un outil en ligne de commande comme rxp, xmllint ou xmlstarlet, on trouve les erreurs suivantes :
il manque la structure englobante html/head/body ;
il manque donc aussi l'élément title dans la partie head ;
le deuxième paragraphe qui commence en ligne 4 n'est pas fermé car il n'y a pas de </p> correspondant à son <p> ;
toujours en ligne 4 l'entité   est mal écrite, il manque un point-virgule en fin d'entité ;
le lien pour Google est incorrect, il faut des guillemets autour de l'URL ;
le lien pour Google est un élément inline et doit être inclus dans un élément de type boite comme par exemple un élément p ou div.
La page m1xml_ok.html contient une version corrigée de la page et avec une indication explicite du jeu de caractères utilisé.
Remarque : une page Web peut comporter autre chose que du HTML ; ainsi les erreurs CSS et JavaScript ne sont pas détectables via ces outils.
2. Passer de XHTML 1.0 Transitionnel à XHTML 1.0 Strict
Quelles sont les principales différences entre les grammaires XHTML 1.0 Transitionnel et XHTML 1.0 Strict ?
Solution : afficher la solution
Comme le montre notre comparateur de grammaires DTD, ce sont surtout les éléments font, iframe et center qui ne sont plus admis en XHTML 1.0 Strict. Ce qui signifie qu'il faut utiliser plus de CSS.
On pourra lire l'article trans-vs-strict pour plus de détails.
Passer de XHTML 1.0 Transitionnel à XHTML 1.0 Strict peut être parfois compliqué. Ainsi pour démarrer une liste avec l'année courante (ici 2017), le code <ol start="2017"... est incorrect car l'attribut start est interdit en XHTML strict. Soit on passe par du CSS (mais cela se généralise mal) soit on utilise du code Javascript pour réaliser un setAttribute("start","2017", ce qui rajoute des difficultés...
3. Créer un document XML qui respecte une grammaire DTD
Nous admettrons pour ce qui suit qu'une molécule est définie par une liste d'atomes avec le nom des atomes, leur notation et le nombre de ces atomes fournis en attributs. Par exemple la molécule d'eau H2O est définie par l'atome de nom hydrogène, de notation H en nombre 2 et par l'atome de nom oxygène, de notation O et en nombre 1 (qui peut donc être omis). Après avoir lu soigneusement le fichier suivant nommé molecule.dtd, écrire un fichier eau.xml valide pour cette grammaire DTD. On utilisera un outil en ligne de commande pour vérifier cette validité. On pourra ignorer les accents.
Fichier molecule.dtd :
<!ELEMENT molecule (atome)+ > <!ELEMENT atome EMPTY > <!ATTLIST atome nom CDATA #REQUIRED > <!ATTLIST atome lettre CDATA #REQUIRED > <!ATTLIST atome nombre CDATA "1" >Est-ce que cette grammaire DTD autorise les chaines vides pour les noms, lettres et nombres ?
Est-ce qu'il faut respecter l'ordre des attributs tel qu'il est défini dans la grammaire DTD ?
Solution : afficher la solution
Voici un fichier eau.xml possible :
<?xml version="1.0" ?> <molecule> <atome nom="Hydrogene" lettre="H" nombre="2" /> <atome nom="Oxygene" lettre="O" nombre="1" /> </molecule>On peut vérifier la validité de ce fichier pour la grammaire molecule.dtd via les commandes suivantes :
xmllint --dtdvalid molecule.dtd --valid eaudtd.xml xmlstarlet val -d molecule.dtd eau.xmlHélas, oui cette grammaire DTD autorise les chaines vides pour les noms, lettres et les nombres car CDATA, comme #PCDATA inclut la chaine vide. On pourra s'en rendre compte avec le fichier suivant eauvide.xml qui est valide pour cette grammaire. Attention : une chaine de caractères réduite à un espace est aussi valide, mais vraiment peut informative...
De la même façon, l'ordre des attributs est libre, à condition qu'un attribut n'apparaisse pas deux fois, comme le montre le fichier suivant, qui est valide pour la DTD considérée :
Fichier eaudtdatt.xml :
<?xml version="1.0" ?> <!DOCTYPE molecule SYSTEM "molecule.dtd"> <molecule> <atome lettre="" nom="" nombre="" /> <atome nombre="" nom="" lettre="" /> </molecule>Voici le message d'erreur en cas de duplication d'attribut, comme c'est le cas pour le fichier eaudtdatt2.xml :
<?xml version="1.0" ?> <!-- fichier eaudtdatt2.xml --> <!DOCTYPE molecule SYSTEM "molecule.dtd"> <molecule> <atome lettre="" nom="" nombre="" /> <atome nombre="" nom="" lettre="" nombre = "" /> </molecule>$gh> xmlstarlet val -e -d molecule.dtd eaudtdatt2.xml eaudtdatt2.xml:5.51: Attribute nombre redefined <atome nombre="" nom="" lettre="" nombre = "" /> ^ eaudtdatt2.xml - invalid
4. Créer un document XML qui respecte une grammaire XSD
On décide maintenant d'utiliser la grammaire molecule.xsd suivante pour stocker les mêmes informations.
Fichier molecule.xsd :
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsd:element name="molecule"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="unbounded" ref="atome"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="atome"> <xsd:complexType> <xsd:sequence> <xsd:element ref="nom"/> <xsd:element ref="nombre"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="nom"> <xsd:complexType> <xsd:simpleContent> <xsd:extension base="xsd:string"> <xsd:attribute name="lettre" use="required" type="xsd:string"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:element> <xsd:element name="nombre" type="xsd:integer"/> </xsd:schema>Ecrire un fichier eau2.xml valide pour cette grammaire XSD. On utilisera un outil en ligne de commande pour vérifier cette validité. Là encore, on pourra ignorer les accents.
Est-ce que cette grammaire XSD autorise les chaines vides pour les noms, lettres et nombres ?
Solution : afficher la solution
Voici un fichier eau2.xml possible :
<?xml version="1.0" ?> <molecule> <atome> <nom lettre="O">Oxygene</nom> <nombre>1</nombre> </atome> <atome> <nom lettre="H">Hydrogene</nom> <nombre>2</nombre> </atome> </molecule>On peut vérifier la validité de ce fichier pour la grammaire molecule.xsd via les commandes suivantes :
xmllint --noout --schema molecule.xsd eau2.xml xmlstarlet val -s molecule.xsd eau2.xmlHélas, oui cette grammaire XSD autorise les chaines vides pour les noms, lettres, mais pas pour les nombres car xs:string inclut la chaine vide. On pourra s'en rendre compte avec le fichier suivant eau3.xml qui est valide pour cette grammaire. Attention : une chaine de caractères réduite à un espace est aussi valide, mais vraiment peut informative...
5. Créer des grammaires DTD et XSD
Disons qu'un trajet ferroviaire est représenté schématiquement mais obligatoirement par un numéro identifiant de trajet, un type de train, un lieu de départ et un lieu d'arrivée. Ces informations sont éventuellement complétées, lorsqu'elles sont disponibles, par deux informations ts (pour time stamp en anglais) qui fournissent respectivement la date et heure de départ et la date et heure d'arrivée.
Voici un exemple de fichier XML regroupant deux trajets, nommé trajets.xml.
Fichier trajets.xml :
<trajets> <trajet id="tr02436"> <train>TGV </train> <depart>Angers</depart> <arrive>Paris Montparnasse</arrive> </trajet> <trajet id="tr5897"> <train>Micheline </train> <depart ts="2016-09-08 13:00">Troyes</depart> <arrive ts="2016-09-08 17:08">Dijon</arrive> </trajet> </trajets>Donner pour ce fichier trajets.xml une grammaire DTD minimale et raisonnable qui permet de décrire les trajets ferroviaires puis une grammaire XSD équivalente.
Solution : afficher la solution
On lira attentivement les fichiers ci-dessous.
Grammaire trajets.dtd :
<!ELEMENT trajets (trajet)+ > <!ELEMENT trajet (train,depart,arrive) > <!ELEMENT train (#PCDATA) > <!ELEMENT depart (#PCDATA) > <!ELEMENT arrive (#PCDATA) > <!ATTLIST trajet xmlns CDATA #FIXED '' id NMTOKEN #REQUIRED > <!ATTLIST depart xmlns CDATA #FIXED '' ts CDATA #IMPLIED > <!ATTLIST arrive xmlns CDATA #FIXED '' ts CDATA #IMPLIED >Grammaire trajets.xsd :
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xsd:element name="trajets"> <xsd:complexType> <xsd:sequence> <xsd:element maxOccurs="unbounded" ref="trajet"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="trajet"> <xsd:complexType> <xsd:sequence> <xsd:element ref="train"/> <xsd:element ref="depart"/> <xsd:element ref="arrive"/> </xsd:sequence> <xsd:attribute name="id" use="required" type="xsd:NCName"/> </xsd:complexType> </xsd:element> <xsd:element name="train" type="xsd:NCName"/> <xsd:element name="depart"> <xsd:complexType> <xsd:simpleContent> <xsd:extension base="xsd:NCName"> <xsd:attribute name="ts"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:element> <xsd:element name="arrive"> <xsd:complexType mixed="true"> <xsd:attribute name="ts"/> </xsd:complexType> </xsd:element> </xsd:schema>Il existe des outils pour créer automatiquement des grammaires à partir d'exemples, comme par exemple trang.
6. Compter des éléments et des attributs
Compter le nombre de lignes puis lister tous les éléments XML distincts utilisés dans le logo du renard ci-dessous, puis compter tous les éléments avec leurs attributs.
Solution : afficher la solution
Il y a en fait assez peu d'éléments utilisés pour le renard. Ainsi la commande xmlstarlet el -u firefox.svg renvoie une liste de 26 éléments distincts dans l'arbre, pour 348 éléments en tout. Si on retire les éléments égaux emboités comme g et g/g, il ne reste que 17 "vrais" éléments utilisés :
# éléments issus de xmlstarlet el -u firefox.svg # éléments uniques 0001 svg 0001 clipPath 0002 svg/desc 0002 defs 0003 svg/g 0003 desc 0004 svg/g/filter 0004 ellipse 0005 svg/g/filter/feGaussianBlur 0005 feGaussianBlur 0006 svg/g/filter/feMerge 0006 feMerge 0007 svg/g/filter/feMerge/feMergeNode 0007 feMergeNode 0008 svg/g/filter/feOffset 0008 feOffset 0009 svg/g/g 0009 filter 0010 svg/g/g/ellipse 0010 g 0011 svg/g/g/g 0011 linearGradient 0012 svg/g/g/g/clipPath 0012 path 0013 svg/g/g/g/clipPath/use 0013 radialGradient 0014 svg/g/g/g/defs 0014 stop 0015 svg/g/g/g/defs/ellipse 0015 svg 0016 svg/g/g/g/linearGradient 0016 title 0017 svg/g/g/g/linearGradient/stop 0017 use 0018 svg/g/g/g/path 0019 svg/g/g/g/radialGradient 0020 svg/g/g/g/radialGradient/stop 0021 svg/g/g/linearGradient 0022 svg/g/g/linearGradient/stop 0023 svg/g/g/path 0024 svg/g/g/radialGradient 0025 svg/g/g/radialGradient/stop 0026 svg/titlePour connaitre les attributs utilisés et pour compter chacun des éléments, on pourrait programmer le comptage des balises d'ouverture et de fermeture, ce que fait notre programme eltattres.php dont l'interface de départ est ici. On pourra cliquer sur le lien elementsRenard pour le vérifier et lire les comptages. On peut aussi enchainer de commandes :
wc -l firefox.svg # 428 lignes xmlstarlet el firefox.svg | wc -l # 348 éléments xmlstarlet el -u firefox.svg | wc -l # 26 éléments xmlstarlet el -a firefox.svg | wc -l # 1311 éléments xmlstarlet el -a firefox.svg | grep "@" | wc -l # 963 attributs
7. Produire du XML avec MySQL
Comment produire des documents XML correspondant aux tables d'une base de données MySQL ?
Solution : afficher la solution
Il y a une option --xml dans les commandes mysql et mysqldump. La démonstration en sera faite dans le cadre du TP.
Questions sans réponse affichée dans le navigateur (donc venez en TP !)
Que faut-il changer dans les fichiers XML et dans les grammaires DTD et XSD précédentes si on décide d'utiliser des accents, que ce soit avec un encodage latin1 ou UTF ?
Est-ce qu'un navigateur peut être validant c'est-à-dire refuser l'affichage d'un document XML s'il n'est pas valide pour la grammaire indiquée en début de document ?
Après avoir vérifié qu'un document DOCX ou ODT est une archive (lisible par exemple par zip), chercher comment on peut lister tous les espaces de noms associés. Où trouve-t-on les grammaires pour ces documents ?
Retour à la page principale de (gH)