\include{parameters}
\usetheme{AFNIC}
\usepackage[french]{babel}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{bortzmeyer-utils}

\title{Les langages de schéma XML}
\author{Stéphane Bortzmeyer\\AFNIC\\\texttt{bortzmeyer@nic.fr}}
\date{14 février 2006}

%\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex} 
% \setlength{\parskip}{15pt} 
\setlength{\parskip}{15pt plus 10pt minus 10pt} 

\begin{document}

\maketitle

\begin{frame}
  \titlepage
\end{frame}

\begin{frame}[fragile]
\frametitle{Exposé libre}
 Ce document est distribué sous les termes de la GNU Free
      Documentation License \url{http://www.gnu.org/licenses/licenses.html#FDL}.
 Permission is granted to copy, distribute and/or modify this document
      under the terms of the GNU Free Documentation License, Version 1.2
      or any later version published by the Free Software Foundation;
      with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.  
\end{frame}

\begin{frame}
\begin{block}{XML n'est pas un langage}{C'est un ensemble de règles de
 syntaxe de bas niveau. La syntaxe de haut niveau et la sémantique, la définition du langage, est
 ailleurs.}\end{block}

Exemples de langages XML :
\begin{itemize}
\item Docbook
\item Atom (format de syndication, RFC 4287)
\item EPP (protocole mais aussi langage, pour définir les éléments XML échangés)
\item IRIS (idem)
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Schéma}

Chaque langage est décrit par un schéma.

Ce schéma peut être écrit dans différents langages.

\begin{itemize}
\item le langage originel, DTD (utilisé par le RFC 2629, par Docbook
  jusqu'à la version 4, l'actuelle),
\item Examplotron, qui permet de créer un schéma à partir d'un
  document exemple,
\item les W3C Schemas, souvent appelés XSD (utilisés par Wikipedia, par SOAP, ou bien pour EPP et IRIS),
\item RelaxNG, le petit dernier (utilisé par OpenDocument, Docbook à
  partir de la version 5, Atom, RFC-editor queue, etc).
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Différentes sortes de langage}
\begin{itemize}
\item Langage à base de \emph{règles} comme Schematron. ``Ce qui doit
être vrai''
\item Langage à base de \emph{grammaire}. ``Ce qui est'' :
\begin{itemize}	
\item Langage de description comme W3C Schema ou DTD. ``Ce qu'il y a
dans un élément.''
\item Langage de motifs comme RelaxNG. ``Ce que doit respecter l'élément''
\end{itemize}
\end{itemize}

Les différences sont subtiles mais peuvent faire la
différence. Certaines constructions ne sont \emph{pas} expressibles en
W3C Schema ou en DTD.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Rappel XML}
XML est hiérarchique.

  \begin{info}
<foo id="exemple">
   <bar/>
</foo>    
  \end{info}

Le tout est un \emph{document} XML, ce qui est entre les étiquettes
\xmltag{foo} et \xmltag{/foo} est un \emph{élement}, qui est à la racine du
document et dont le \emph{contenu} est un autre élement. 

\xmltag{bar/} est un élément vide, \emph{fils} de l'élement \xmltag{foo}. 

``id'' est un \emph{attribut}.

\end{frame}

\begin{frame}[fragile]
  \frametitle{Bien formé et valide}
Tout document XML est \emph{bien formé}. Sinon, c'est une erreur.

\begin{info}
  <!-- Pas bien forme -->
  <foo><bar/></fou>
\end{info}

\begin{info}
  <!-- Pas bien forme -->
  <foo><baz></foo></baz>
\end{info}

\end{frame}

\begin{frame}[fragile]
\frametitle{Validité}
Certains documents XML sont \emph{valides}, selon un \emph{schéma}
écrit dans un langage de schéma comme DTD ou RelaxNG.

\begin{info}
  <!-- Bien forme mais pas valide selon la DTD Docbook -->
  <article>Texte</article>
\end{info}

Après le fait d'être \emph{bien formé} et la \emph{validité}, il y a
le respect des \emph{règles métier} (tout ne peut pas être mis dans le
schéma).

\end{frame}

\begin{frame}[fragile]
\frametitle{Les \foreign{namespaces}}
Si on veut mélanger des éléments de plusieurs vocabulaires.
\begin{info}
  <afnic:domain holder='AR41-NIC'>
     <afnic:name>example.fr</afnic:name>
     <afnic:active/>
     <inpi:mark final='1'>123456789</inpi:mark>
  </afnic:domain>
\end{info}
Les préfixes des espaces de noms (ici, ``afnic'' et ``inpi'') sont
définis par un URI (RFC 3305). C'est l'URI qui compte, \textbf{pas} le préfixe :
\begin{info} 
<afnic:domain holder='AR41-NIC' 
         xmlns:afnic="http://www.afnic.fr/Confiance" >
     <afnic:name>example.fr</afnic:name>
     <afnic:active/>
     <inpi:mark final='1' xmlns:inpi="urn:INPI">123456789</inpi:mark>
  </afnic:domain>
\end{info}
\end{frame}

\begin{frame}
  \frametitle{Pourquoi un langage de schéma ?}
Avoir un schéma pour ses documents XML n'est \emph{pas} obligatoire.

Mais cela permet :
\begin{itemize}
\item de les valider, donc de simplifier l'application qui les traite,
\item et de guider le processus d'édition.
\end{itemize}

\end{frame}

\begin{frame}
\frametitle{Caractéristiques du langage}
Il y a deux choses à décrire dans un schéma :
\begin{enumerate}
  \item La \emph{structure}, c'est-à-dire la combinaison des éléments
  (le fait que tout \xmltag{article} doive avoir un \xmltag{title} par
  exemple). C'est le rôle d'une grammaire.
\item Le contenu des éléments, autrement dit leur \emph{type} (le fait
  que \xmltag{date} doive contenir un truc de la forme YYYY-MM-DD par
  exemple ou bien que \xmltag{salary} doive être un entier positif).
\end{enumerate}
Tous les langages de schéma séparent ces deux aspects.
\end{frame}

\begin{frame}
\frametitle{Ambigüité et non-déterminisme}  
\begin{itemize}

  \item L'ambigüité est le fait que deux alternatives de la grammaire
  puissent valider un document. 

Par exemple, la grammaire \computer{"a" / "b"* "a"} est ambigüe car la
lettre ``a'' peut être validée par les deux termes de l'alternative.

Pas gênante pour valider mais plus embêtant pour l'édition guidée.

\item Le non-déterminisme (l'ambigüité implique le non-déterminisme)
  est le fait que l'analyseur doive parfois regarder en avant pour
  savoir quelle branche de la grammaire prendre.

Ainsi, \computer{"a" / "a" "b"} n'est pas ambigüe mais est non-déterministe.
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Exemple de langage XML}
Pour les exemples, nous prendrons l'exemple suivant :
\begin{enumerate}
  \item<2->Un registre de noms de domaines est régi par la loi du 9
    juillet 2004 qui dit que « En cas de cessation de l'activité de
    ces organismes, l'État dispose du droit d'usage de la base de
    données des noms de domaine qu'ils géraient. ». Il faut donc un
    dispositif de \emph{séquestre}, pas de simple sauvegarde. On
    choisit XML.
\item<3->On va donc créer un schéma pour décrire la base de données du
  registre, avec des \xmltag{domain} et des \xmltag{contact}.
\end{enumerate}
\end{frame}

\begin{frame}[fragile]
\frametitle{Un exemple de zone}
\begin{info}
<zone name="fx">
   <domain>
      <name>foobar.fx</name>
      <holder>AB1-FXNIC</holder>
      <created>2006-01-16</created>
   </domain>
   <contact publish="false">
     <name>Bortzmeyer</name><firstname>Stephane</firstname>
     <handle>SB1-FXNIC</handle>
     <phone>+33 1 39 30 83 46</phone>
     <email>foo@bar</email>
   </contact>
</zone>
\end{info}
\end{frame}

\begin{frame}[fragile]
  \frametitle{DTD, l'ancêtre et ses limites}
Le langage original, issu de SGML.
  \begin{itemize}
  \item Syntaxe pas XML (avantage ou inconvénient ?)
  \item Uniquement la structure, pas les types
  \item Contraintes d'intégrité (ID/IDREF)
  \end{itemize}
  \begin{info}
<!ELEMENT domain (name,nameservers?,holder,tech?,admin?,created)>

<!ELEMENT contact (name,firstname?,handle,address*,city?,country?,phone?,email)>
<!ATTLIST contact publish NMTOKEN "false">

<!ELEMENT name (#PCDATA)>
<!ELEMENT firstname (#PCDATA)>
<!ELEMENT handle (#PCDATA)>
<!ELEMENT holder (#PCDATA)>   
  \end{info}
\end{frame}
   
\begin{frame}
\frametitle{Ce qu'on ne peut pas faire avec la DTD}
\begin{itemize}
\item Spécifier la syntaxe d'une date ou d'un booléen comme publish
\item Spécifier des cardinalités autre que 0, 1 ou N
\item Spécifier des contraintes d'intégrité avec les éléments (mais on
peut avec les attributs)
\item Ne \emph{pas} spécifier d'ordre sur les éléments (\xmltag{phone}
et \xmltag{email})
\end{itemize}
\end{frame}
    
\begin{frame}
    \frametitle{Alors, DTD ou pas DTD ?}
    \begin{block}{Le Cobol des langages de schéma}
    {Tout le monde déteste et sait que c'est archaïque mais elles sont
    très répandues et beaucoup d'outils existent.}
    \end{block}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Examplotron}
  \begin{block}
  {Modéliser commence souvent par un exemple}
  {Les sessions de \foreign{brainstorming} travaillent en général
  mieux avec des exemples qu'avec des schémas. 

Le principe est donc simple : un schéma est un document d'exemple
  comme celui vu plus haut.}
  \end{block}

\only<2->{Principale faiblesse : comment savoir si un élement est optionnel ou
  pas ?}

\only<3->{On enrichit donc le document avec des annotations.}
\end{frame}

\begin{frame}[fragile]
\frametitle{Examplotron avec annotations}
\begin{info} 
... xmlns:eg="http://examplotron.org/0/" ... 
  <contact publish="true" >
      <name>Renard</name><firstname>Annie</firstname>
      <handle>AR41-FXNIC</handle>
      <email>ar@nic.fx</email>
      <!-- Numero de telephone optionnel -->
      <phone eg:occurs="?">+33 1 39 30 00 41</phone>
   </contact>
\end{info}

\only<2->{Examplotron trouve tout seul les types mais on peut les
  forcer le cas échéant.}

\end{frame}

\begin{frame}
\frametitle{Mise en \oe{}uvre d'Examplotron}
Une feuille de style XSLT traduit le document exemple en schéma
RelaxNG.

On peut donc utiliser n'importe quel outil RelaxNG.
\end{frame}

\begin{frame}
\frametitle{W3C Schemas, l'officiel}  

W3C Schemas, le langage d'EPP et d'IRIS.

Normalisé par le W3C. Bénéficie du meilleur \foreign{mindshare} : pour
les lecteurs de 01, c'est un synonyme de schéma.

Syntaxe XML.

\end{frame}

\begin{frame}[fragile]
\frametitle{Un schéma W3C}
\begin{info}
  <schema:element name="domain">
    <schema:complexType>
      <schema:sequence>
        <schema:element name="name" type="schema:string"/>
        <schema:element name="holder" type="schema:IDREF"/> 
        <schema:element name="created" type="schema:date"/>
      </schema:sequence>
    </schema:complexType>
  </schema:element>
   <schema:element name="contact">
    <schema:complexType>
      <schema:sequence>
        <schema:element name="name" type="schema:string"/>
        <schema:element name="firstname" type="schema:string"/>
        <schema:element name="email"  type="email-address" minOccurs="0"/>
        <schema:element name="phone"  type="schema:string" minOccurs="0"/>
      </schema:sequence>
      <schema:attribute name="publish" type="schema:boolean"/>
    </schema:complexType>
  </schema:element>
\end{info}
\end{frame}

\begin{frame}[fragile]
\frametitle{Exemple IRIS}
RFC 3982 :
\begin{info}
     <complexType
       name="domainType">
       <complexContent>
         <extension
           base="iris:resultType">
           <sequence>
             <element name="domainName"  type="token" />
             <element
               name="nameServer"
               type="iris:entityType"
               minOccurs="0"
               maxOccurs="unbounded" />
             <element
               name="registrant"
               type="iris:entityType"
               minOccurs="0"
               maxOccurs="1" />
             <element name="status"       minOccurs="0"                maxOccurs="1">
               <complexType>
                 <all>
                   <element
                     name="reservedDelegation"
                     minOccurs="0"
                     maxOccurs="1"
                     type="dreg:domainStatusType" />
                   <element
                     name="assignedAndActive"
                     minOccurs="0"
                     maxOccurs="1"
                     type="dreg:domainStatusType" />
\end{info}
\end{frame}

\begin{frame}
\frametitle{W3C Schemas ou pas}
Très verbeux, en partie en raison de la syntaxe XML : l'éditer à la
main est difficile.

Paradoxalement peu d'outils, surtout en logiciel libre.

Des restrictions pénibles dans le langage.
\end{frame}

\begin{frame}[fragile]
  \frametitle{RelaxNG, le \textit{challenger}}

\url{http://www.relaxng.org/}

Le langage de Docbook et d'Atom. Préféré par Oasis.

Deux syntaxes, XML et compacte.

Ne spécifie que la structure et compte sur une bibliothèques de
types pour le contenu.

\begin{info}
valid_domain_name = 
      xsd:string {pattern = "[A-Za-z0-9\-\.]+"}
domain = element domain 
            {domain_name & holder & created}
contact = element contact 
            {publish?, (firstname & name & handle & email? & phone?)}
domain_name = element name 
                  {valid_domain_name}
created = element created {xsd:date}
publish = attribute publish {xsd:boolean}
\end{info}
\end{frame}

\begin{frame}[fragile]
\frametitle{RelaxNG, exemple}

Extrait d'Atom

\begin{info}
   element atom:entry {
         atomCommonAttributes,
         (atomAuthor*
          & atomId
          & atomRights?
          & atomTitle
          ...
      }
   atomAuthor = element atom:author { atomPersonConstruct }
   atomPersonConstruct =
      atomCommonAttributes,
      (element atom:name { text }
       & element atom:uri { atomUri }?
       & element atom:email { atomEmailAddress }?
       ...)
\end{info}
\end{frame}

\begin{frame}
\frametitle{Le cas particulier du Schematron}
\url{http://www.schematron.com/}

Schematron est un langage d'\emph{assertions} sur les documents. Par exemple
``tout élement \xmltag{domain} doit avoir au moins deux éléments
\xmltag{nameserver}''. Ces assertions sont exprimées en Xpath.

Il peut être utilisé seul ou bien en conjonction avec un autre langage
de schémas.

\end{frame}

\begin{frame}[fragile]
\frametitle{Exemple Schematron}
\begin{info}
<?xml version="1.0"?>
<schema xmlns="http://www.ascc.net/xml/schematron" xmlns:axsl="http://www.w3.org/1999/XSL/Transform">
  <pattern>
    <rule context="foo">
      <assert test="bar">
         We need at least one bar
      </assert>
      <assert test="@id">
         We need the ID of the foo
      </assert>
    </rule>
    <rule context="bar">
      <assert test="count(descendant::*) = 0">
          bar must not have subelements
      </assert>
    </rule>
  </pattern>
</schema>
\end{info}
\end{frame}

\begin{frame}[fragile]
\frametitle{Combiner Schematron et Relax-NG}

Ici, pour exprimer une contrainte d'intégrité (le \foreign{handle} du
titulaire doit exister).

\begin{info}
domain =
  element domain { domain_name
    & holder 
       >> sch:pattern [
           name = "Integrity reference for holder"
           sch:rule [ context = "domain" 
             sch:assert [test = "/zone/contact[handle=current()/holder]"  
             "The " sch:name [] sch:value-of [select = "name"] " has an invalid holder"]]]
    & created
  }
\end{info}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Bibliothèque de types}
Certains langages de schéma comme RelaxNG ne gèrent que la structure.

Pour le type (le contenu des éléments), il faut un autre langage.

On peut utiliser une bibliothèque de types existantes comme celle des
W3C Schema.

Ou bien avoir un langage d'écriture de types comme DTLL
\url{http://www.jenitennison.com/datatypes/DTLL.html} ou comme rnv,
avec qui on peut créer ses propres types en Scheme :
\begin{info}
  (define addr-spec-regex
  (let* (
      (atom "[a-zA-Z0-9!#$%&'*+\\-/=?\\^_`{|}~]+")
      (person "\"([^"\\\\]|\\\\.)\"")
      (location "\\[([^\\[\\]\\\\]|\\\\.)*\\]")
      (domain (string-append atom "(\\." atom ")*")))
    (string-append
      "(" domain "|" person ")"
      "@"
      "(" domain "|" location ")")))
\end{info}
\end{frame}

\begin{frame}[fragile]
\frametitle{Ouverture des schémas}
Il est souvent souhaitable de modifier un schéma, de l'étendre ou bien
de le réutiliser.

L'ouverture d'un schéma (sa capacité à être modifié, étendu ou
réutilisé) ne dépend pas que du langage mais aussi de l'auteur.

Exemple de schéma rigide en RelaxNG :

\begin{info}
foo = element foo {element bar {text}}
\end{info}

Exemple de schéma ouvert en RelaxNG :

\begin{info}
bar = element bar {text}
foo = element foo {bar}
\end{info}

\xmltag{bar} peut maintenant être utilisé seul.

\end{frame}

\begin{frame}[fragile]
\frametitle{Ouverture de notre schéma}

Le schéma original :

\begin{info}
domain = element domain {domain_name & holder & tech & created}
tech = tech_contact # Exactly one
tech_contact = element tech {xsd:NMTOKEN}
\end{info}

Le schéma étendu pour admettre plusieurs contacts techniques :
\begin{info}
include "../domain-escrow/relaxng-schema.rnc"
tech &= tech_contact* # Merge with previous definition
\end{info}
\end{frame}

\begin{frame}[fragile]
\frametitle{Ouvrir, autre exemple}
\begin{info}
domain = element domain {domain_items}
domain_items = domain_name & holder & tech & created
\end{info}

Ainsi, on peut ajouter des attributs ou des éléments à \xmltag{domain}
sans changer le schéma :
\begin{info} 
uname = element uname {text} # Unicode name of the domain
domain_items &= uname?
\end{info}
\end{frame}

\begin{frame}[fragile]
\frametitle{\textit{namespaces}}
Il n'y a pas encore de mécanisme de schéma
multi-\foreign{namespaces}. Exemple : un flux Atom qui contient de
l'XHTML. Il n'y a pas de moyen propre de valider le contenu XHTML
selon le schéma de XHTML.

Une proposition : NRL (\foreign{Namespace Routing Language}) \url{http://www.thaiopensource.com/relaxng/nrl.html}

\begin{info}
<rules xmlns="http://www.thaiopensource.com/validate/nrl">
  <namespace ns="http://www.w3.org/2005/Atom">
    <validate schema="atom.rnc"/>
  </namespace>
  <namespace ns="http://www.w3.org/1999/xhtml">
    <validate schema="xhtml.rng"/>
  </namespace>
</rules>
\end{info}
\end{frame}

\begin{frame}[fragile]
\frametitle{D'un langage à l'autre}
trang \url{http://www.thaiopensource.com/relaxng/trang.html} convertit
d'un langage de schéma dans l'autre.

\begin{info}
%.dtd: %.rnc
        trang -Irnc -Odtd $< $@

%.xsd: %.rng
        trang -Irng -Oxsd $< $@
\end{info}

\end{frame}

\begin{frame}
  \frametitle{Outils de validation}
  Ligne de commande ou bibliothèque, le choix est vaste. Il existe
  même des \foreign{appliances} (\url{http://www.datapower.com/products/xa35.html} ou \url{http://www.sarvega.com/xml-processing.html}).

Attention : certains font souvent des faux négatifs (documents
acceptés à tort).
\end{frame}

\begin{frame}[fragile]
  \frametitle{xmllint}
Ce programme fait partie de la \emph{libxml2} de Gnome, écrite par
Daniel Veillard. 

Mais il peut s'utiliser sans Gnome.

Il sait valider contre une DTD, un schéma RelaxNG (des bogues avec les
\foreign{interleaves}) ou un schéma W3C (tout n'est pas implémenté).

\begin{info}
xmllint --noout --dtdvalid dtd-schema.dtd example.xml
xmllint --noout --relaxng relaxng-schema.rng example.xml
xmllint --noout --schema w3c-schema.xsd example.xml
\end{info}
\end{frame}
    
\begin{frame}[fragile]
  \frametitle{jing} jing
\url{http://www.thaiopensource.com/relaxng/jing.html} est écrit en
Java et donc peu portable.

Ne connait que RelaxNG.

\begin{info}
java -jar /local/lib/jing.jar relaxng-schema.rng example.xml
\end{info}
\end{frame}
    
\begin{frame}[fragile]
  \frametitle{rnv}
Écrit en C \url{http://www.davidashen.net/rnv.html}

Ne connait que RelaxNG/compact.

\begin{info}
rnv relaxng-schema.rnc example.xml
\end{info}
\end{frame}
    
\begin{frame}
  \frametitle{Outils d'édition guidée}

Édition guidée : complétion des \foreign{tags}, affichage des choix
possibles, mode \foreign{outline}, etc.

nxml mode \url{http://www.thaiopensource.com/download/} est un mode
Emacs. Le schéma doit être en RelaxNG/compact.

psgml \url{http://www.lysator.liu.se/~lenst/about_psgml/} est un mode Emacs pour SGML et qui marche donc pour XML. DTD
seulement.

\end{frame}

\begin{frame}
\frametitle{Premier exercice}
\begin{block}
{Termes interdits}
{Modéliser en Examplotron une liste de termes interdits}
\end{block}

\begin{enumerate}
\item<2->Quels éléments ? 
\item<3->Quel type ?
\end{enumerate}
\end{frame}

\begin{frame}
\frametitle{Deuxième exercice}
\begin{block}
{Listes de domaines pour lesquels on est secondaire}
{Modéliser en RelaxNG une liste de domaines dont on assure le DNS secondaire}
\end{block}

\begin{enumerate}
\item<2->Quels éléments ? 
\item<3->Quel type ?
\end{enumerate}
\end{frame}

\end{document}
