eXtensible Markup Language

est il encore utile en 2020  ?

CC-BY-NC-4.0 / Septembre 2020 / Loïc TRUCHOT

Devinette

Pourquoi AJAX s'appelle AJAX ?

Workshop

  • Créer un nouveau fichier livres.txt
  • Décrire 2 livres d'informatique dans ce fichier
  • Partager ce fichier sur slack
  • Choisissez le fichier d'un autre et comparer avec le vôtre

Les données structurées

  • La base de la communication (un langage commun)
  • La base des sciences de l'information, et de l'informatique
  • Conditionne la lecture de fichier
  • Conditionne les boucles
  • Conditionne le big data
  • Conditionne les échanges sur le web
  • Pas de vérité: des conventions

Workshop

  • Utiliser JavaScript pour lire un des fichiers
  • N'afficher dans la console que les titres
// Read the file and print its contents as an array.
var fs = require("fs");
var content = fs.readFileSync("./toto.txt", "utf8");
var livres = content.split("\r\n");
console.log(livres);
  • Si besoin, modifier le fichier jusqu'à ce que la consigne soit réalisable !
  • Bonus: donner un prix à chaque livre et afficher dans la console uniquement le moins cher et le plus cher

Citez quelques formats de données

  • Lesquels sont des languages de balises ?

JSON

JavaScript Object Notation

XML

eXtensible Markup Language

Formats textuels d'échange sur le web

YAML

Yet Another Markup Language

HTML, SVG, RSS...

et XHTML... Des formats déjà contraints, basés sur XML qui est libre et extensible

<livre>
    <titre>SICP</titre>
    <auteur>Hal Abelson</auteur>
</livre>
"livre": {
  "titre": "SICP",
  "auteur": "Hal Abelson"
}
livre:
  titre: SICP
  auteur: Hal Abelson

Workshop

  • Convertissez vos livres en XML
  • Installer  package JS pour lire le XML
  • Afficher la liste des auteurs dans la console
var parser = require("fast-xml-parser");
var fs = require("fs");
var content = fs.readFileSync("./books.xml", "utf8");

if (parser.validate(content)) {
  var xmlData = parser.parse(content);
  console.log(xmlData.livre);
}

une histoire du XML

  • 1969, Charles Goldfarb invente SGML pour IBM
  • 1984, l'UE apopte SGML pour l'encodage de documents complexes
  • 1995, la W3C adopte SGML comme standard d'échange de donnée
  • 1998, XML 1.0 est validé, après plusieurs années de consensus entre grand noms du web et de la documentation
  • XML est plus simple et plus strict que SGML, pour un standard amélioré
  • 2000, le succès de XML provoque le XHTML (HTML 4)
  • 2004, XML 1.1

La réponse en un graphique

  • 50/50 du fait des anciennes API
  • Les nouvelles API, ou les anciennes très utilisée proposent les deux, car conversion simple
  • Mon expérience: FFBB, météo, aéroport, population/statistiques
  • De nombreuses extensions: docx

Workshop

  • Trouver une api présentant des données libre (open data, free, etc.) sous un format XML ou JSON
  • Partagez sur slack

Les webservices

 

  • des API à consommer
  • des microservices, publics ou privés
  • wikipedia, facebook, google, open weather, open street map, etc.

Un vrai fichier XML à la loupe

  • prologue, racine, balises, attributs, arborescence
  • la racine suit directement le prologue (pas de saut de ligne)
  • Un compromis entre l'homme et la machine
  • Un arbre comme les autres
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<racine>
  <balise attr="valeur">valeur</balise>
  <balise attr="valeur">valeur</balise>
  <arbo>
  	<branche attr="valeur">valeur</branche>
  </arbo>
  <!-- Et un petit commentaire -->
</racine>

Petit débat sans violence

Peut-on tout encoder en XML ?

Workshop

  • Parmi les idées évoquée précédemment, créer un vrai XML
  • Trouver un moyen de vérifier l'intégrité de votre XML et partagez sur slack
  • Partager votre XML sur slack, consultez ceux des autres

Arborescence, balise ou attribut ?

  • Arbo: assembler des entitées liées, des listes
  • Balise: Désigner le "type" d'objet, le "sens"
  • Dans la balise: Valeur utile
  • Attribut: Ajouter une qualification (ou metadonnee), parfois seulement utile pour l'humain - unique pour chaque objet

Pas de règle universelle...

Les règles

  • Faire des balises/attributs sémantiques
  • Ne pas utiliser de caractères spéciaux (ex: accents) ni d'espace dans le nom des balises
  • Ne pas utiliser de majuscules, ni de camel-case (ça marche, mais présente un risque)
  • Ne pas commencer par un chiffre
  • Si absolument besoin:
    • utilisez _ pour séparer les concepts

Workshop

  • Corrigez le XML que vous voulez utiliser
  • Donnez votre XML au formateur, pour qu'il le déploie sur le serveur
  • Installez les dépendances NPM axios et xml-js
  • Présenter ces données dans le html grâce à JavaScript
import axios from 'axios';
import convert from 'xml-js';

axios
  .get('https://mini-xml-server.committers.ngo/books.xml')
  .then((response) => {
  
    var data = convert.xml2js(response.data, { compact: true });
  
    for (var livre of data.livres.livre) {
      var el = document.createElement('div');
      el.innerText = livre.auteur._text;
      document.body.appendChild(el);
    }
  
  });

Workshop

  • Hackez wikipedia !
  • Trouvez l'image d'un contenu en fouillant son XML
https://fr.wikipedia.org/w/api.php?page=Moineau domestique
	&format=xml&action=parse

Workshop

  • Alimentez un portail de lien avec du XML
  • Creez un formulaire basé sur le XML à envoyer
  • Lorsq'on clique sur "envoyer", une requête ajax envoie un XML de la forme suivante (utilisez les templated strings):
  <lien>
    <titre>Elm</titre>
    <image>https://toto.png</image>
    <url>https://elm-lang.org/</url>
    <desc>Le meilleur language de programmation.</desc>
    <nom>Loïc T.</nom>
  </lien>
  • Le "endpoint" est décrit ici.
axios
  .post('https://mini-xml-server.committers.ngo/portail', xmlStr, {
    headers: { 'Content-Type': 'application/xml' },
  })
  .then((response) => {
    console.log(response);
  });

Les DTD

  • Pourquoi HTML a un set de balise fini et distinctes ?
  • Pourquoi cela a un intérêt pour nous ?
  • Qu'est-ce qu'une DTD ?

Document
Type

Definition

  • Doctype et racine
  • ELEMENT
  • #PCDATA
  • ATTLIST
  • CDATA
  • #IMPLIED
  • #REQUIRED
<?xml version = "1.0" encoding="UTF-8" ?>
<!DOCTYPE livres [
  <!ELEMENT livres (livre*)>
  <!ELEMENT livre (titre, auteur)>
  <!ELEMENT auteur (#PCDATA)>
  <!ELEMENT titre (#PCDATA)>
  <!ATTLIST titre soustitre CDATA #IMPLIED>
]>
<livres>
    <livre>
        <titre soustitre="toto">SICP</titre>
        <auteur>Hal Abelson</auteur>
    </livre>
    <livre>
        <titre>PICS</titre>
        <auteur>Hal Abelson</auteur>
    </livre>
    <livre>
        <titre soustitre="titi">PSIC</titre>
        <auteur>Hal Abelson</auteur>
    </livre>
</livres>

Workshop

DTD

corner cases

  • plusieurs attributs
  • plusieurs éléments similaires
  • ANY, EMPTY
  • ?, +, *, |, ,, ()
  • toutes listes ordonnées...
<?xml version = "1.0" encoding="UTF-8" ?>
<!DOCTYPE livres [
  <!ELEMENT livres (titre, livre*)>
  <!ELEMENT livre (titre+, vendu*)>
  <!ELEMENT titre (#PCDATA|(nom,categorie))>
  <!ELEMENT nom (#PCDATA)>
  <!ELEMENT categorie (#PCDATA)>
  <!ELEMENT vendu EMPTY>
  <!ATTLIST titre 
    soustitre CDATA #IMPLIED
    prix CDATA #IMPLIED
  >
]>
<livres>
    <titre>
        <nom>Les livres noirs</nom>
        <categorie>policier</categorie>
    </titre>
    <livre>
        <titre soustitre="toto" prix="34">
          SICP
        </titre>
        <vendu />
    </livre>
    <livre>
        <titre>PICS</titre>
    </livre>
</livres>

Workshop

  • Faire la DTD du XML d'un autre
  • Faire le XML de la DTD d'un autre

Les entités

  • Remplace une chaîne de caractères
  • Comme en html: commence par &, fini par ;
  • Natives: &lt; <, &gt;>, &amp; &, &quot; ", &apos; '
  • Se déclarent dans la DTD et s'utilisent ainsi:
<?xml version="1.0"?>
<!DOCTYPE tutorials [
    <!ENTITY header "Bienvenue sur ce tuto !">
<]>
<tutorials>
  <tutorial>
    <name>XML</name>
    <header>&header;</header>
  </tutorial>
  <tutorial>
    <name>HTML</name>
    <header>&header;</header>
  </tutorial>
</tutorials>

La DTD externe

  • Un fichier séparé
  • Un lien dans le doctype du XML
  • Un chemin relatif vers une extension .dtd
  • Attention: cela rompt l'unité du document
<!ELEMENT livres (livre*)>
<!ELEMENT livre (titre, auteur)>
<!ELEMENT auteur (#PCDATA)>
<!ELEMENT titre (#PCDATA)>
<!ATTLIST titre soustitre CDATA #IMPLIED>

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE livres SYSTEM "livres.dtd">
<livres>
    <livre>
        <titre>SICP</titre>
        <auteur>Hal Abelson</auteur>
    </livre>
    <livre>
        <titre>The Little Schemer</titre>
        <auteur>D. Friedman</auteur>
    </livre>
</livres>

livres.xml

livres.dtd

Commentaires

Comme en HTML,

sur une ou plusieurs lignes

Grands échappements

Echapper plus d'un caratère peut vite devenir problématique

Dans ce cas, utiliser CDATA

<text> 
  <![CDATA[
    1 < 3 mais 1 > 0...
  ]]>
</text> 
<text> 
  <!-- FIXME: trouver un texte -->
</text> 

Tooling

// vs code settings
"xml.java.home": "C:\\Program Files (x86)\\Java\\jre1.8.0_261",
"xml.validation.enabled": true

XML Schema, pourquoi ?

  • XSD - XML Schema Definition
  • Comme une DTD mais...
    • Moins de "corner cases"
    • Précision dans l'enchevêtrement des balises
    • Types spécifiques pour chaque balise et attribut
    • Écrire la définition de son XML... en XML !
  • Mais... plus verbeux, plus "bruyant", moins commun

XML Schema

Definition

  • Doit être externe
  • Référence le NameSpace de XS
  • Est appelé dans la racine du XML
  • Type simple
  • Type complexe
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="livres" />
  <xs:element name="livre">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="titre" type="xs:string"/>
        <xs:element name="auteur" type="xs:string"/>
        <xs:element name="annee" type="xs:integer"/>
        <xs:element name="prix" type="xs:decimal"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<livres 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:noNamespaceSchemaLocation="livres.xsd">
    <livre>
        <titre>SICP</titre>
        <auteur>Hal Abelson</auteur>
        <annee>1979</annee>
        <prix>49.99</prix>
    </livre>
</livres>

XS Attributs

  • ou comment le boilerplate m'a fait préférer les DTD
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="livres" />
    <xs:element name="livre">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="titre" type="xs:string"/>
                <xs:element name="auteur" type="xs:string"/>
                <xs:element name="annee" type="xs:integer"/>
                <xs:element name="prix">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:decimal">
                                <xs:attribute name="devise" type="xs:string" use="required" />
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="en_stock" type="xs:boolean" />
        </xs:complexType>
    </xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<livres 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="livres.xsd">
    <livre en_stock="true">
        <titre>SICP</titre>
        <auteur>Hal Abelson</auteur>
        <annee>1979</annee>
        <prix devise="euro">49.99</prix>
    </livre>
</livres>

En remplacements de la DTD

  • la séquence + devient: <xs:sequence>
  • le désordre autorisé: <xs:all>
  • le nombre d'occurence
    • minOccurs="0"
    • maxOccurs="unbounded"
      • ou des nombres bien sûr

"ref" pour "limiter" la complexité

<xs:element name="prix">
        <xs:complexType>
            <xs:simpleContent>
                <xs:extension base="xs:decimal">
                    <xs:attribute name="devise" type="xs:string" use="required" />
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
    </xs:element>
    <xs:element name="livre">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="titre" type="xs:string"/>
                <xs:element name="auteur" type="xs:string"/>
                <xs:element name="annee" type="xs:integer"/>
                <xs:element ref="prix" />
            </xs:sequence>
            <xs:attribute name="en_stock" type="xs:boolean" />
        </xs:complexType>
    </xs:element>

Workshop

  • Ecrire une XSD pour le fichier vétérinaire suivant
  • Ne pas oublier de le lier et de le tester
<?xml version="1.0"?>
<animaux>
    <animal visite="true">
        <name>Puce</name>
        <age>14</age>
        <type>chat</type>
        <color>argent</color>
    </animal>
    <animal visite="false">
        <name>Amanda</name>
        <age>10</age>
        <type>chien</type>
        <color>marron</color>
    </animal>
    <animal visite="false">
        <name>Jack</name>
        <age>3</age>
        <type>chat</type>
        <color>noir</color>
    </animal>
    <animal visite="true">
        <name>Bernard</name>
        <age>12</age>
        <type>chien</type>
        <color>bleu</color>
    </animal>
    <animal visite="false">
        <name>Naia</name>
        <age>1</age>
        <type>chat</type>
        <color>marron</color>
    </animal>
    <animal visite="true">
        <name>Stop</name>
        <age>5</age>
        <type>cochon</type>
        <color>marron</color>
    </animal>
</animaux>

Types affinés

  • string, date, language, time, decimal, integer, boolean...
  • Et restriction spécifiques...
  • Liste : https://www.w3schools.com/xml/schema_dtypes_string.asp

Options bonus

  • <xs:any />
  • <xs:anyAttribute/>
<xs:element name="age">
  <xs:simpleType>
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="0"/>
      <xs:maxInclusive value="120"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

Epreuve

Pour aller plus loin...

  • XSLT
  • XPath
  • Maven et pom.xml, API Java

Ressources

THANK'S EVERYONE
It's finally done ! See you soon

Made with Slides.com