Accueil
 chercher             Plan du site             Info (English version) 
L'histoire de XML s'écrit en ce moment même. XMLfr vous aide à la suivre et à en dégager les tendances.Les listes de discussions XMLfr sont à votre disposition pour réagir sur nos articles ou simplement poser une question.Si vous ètes passionnée(e) par XML, pourquoi ne pas en faire votre métier ?XMLfr n'est heureusement pas le seul site où l'on parle de XML. Découvrez les autres grâce à XMLfr et à l'ODP.Les partenaires grâce auxquels XMLfr peut se développer.Pour tout savoir sur XMLfr.XMLfr sans fil, c'est possible !Pour ceux qui veulent vraiment en savoir plus sur XML.L'index du site.
 Si vous vous posez une question, vous n'êtes peut-être pas le premier...Les traductions en français des bibles XML.Ces articles sont des références dans leur domaine.Tout ce qu'il faut savoir pour démarrer sur un sujet XML...


DTD+RE

Devant la complexité et la verbosité des langages de schémas XML, de nombreux experts regrettent que l'on n'ait pas cherché à faire évoluer les DTDs (et les dizaines d'années d'expérience qui y sont associées) plutôt que de réinventer la roue. Dans cette logique, François Perrad propose ici une extension des DTDs permettant d'utiliser des expressions régulières pour spécifier le contenu des attributs et des éléments.

Par François Perrad (francois.perrad(at)gadz.org).
mardi 29 juillet 2003

Contenu

Introduction

L'idée d'ajouter des expressions régulières aux DTD XML m'est venue, il y a quelque temps déjà. Mais c'est la lecture récente de deux livres : 'Mastering Regular Expressions' de Jeffrey E. F. Friedl et 'XML Schema' de Eric van der Vlist qui m'a poussé à la formaliser et à écrire cet article.

Cette idée m'est venue naturellement car j'ai une vue très grammaticale des DTD, ce qui est certainement dû à des souvenirs de lex et yacc.

XML est un langage puissant pour décrire toutes sortes de données. Mais c'est surtout un moyen pour les échanger, donc une syntaxe de transfert. Pour être comprises, ces données doivent respecter un schéma c'est-à-dire correspondre à une syntaxe abstraite. Les DTD ont été le premier type schéma. Les DTD n'utilisent pas elles-mêmes XML.

Je comprends mal pourquoi les nouveaux types de schéma tel que W3C XML Schema et RELAX NG qui ont pour but de décrire une syntaxe abstraite, le font en utilisant XML qui est une syntaxe de transfert. Le résultat est verbeux et rend la conception inintelligible à la lecture bien qu'humainement lisible (ce qui est une des forces de XML). Ces deux approches montrent une des limites de XML, il peut tout représenter, mais pas toujours très efficacement. D'ailleurs, James Clark vient d'ajouter une syntaxe compacte à RELAX NG dont le premier objectif est de maximiser la lisibilité.

Mon objectif n'est pas de concurrencer ces nouveaux types de schéma. Ils reposent sur une approche orientée objet et correspondent à un certain type de besoin.

Mes objectifs sont :

  • de garder la simplicité des DTD et leur approche grammaticale.
  • d'augmenter le niveau de validation

Si on reprend l'approche grammaticale, les DTD permettent une bonne validation au niveau de la structure syntaxique (c'est-à-dire correspondant à yacc), mais au niveau des lexèmes (correspondant à lex) elles n'offrent pas beaucoup de possibilités : soit un ensemble de valeurs prédéfinies, soit un texte libre ou presque comme les NMTOKEN, mais rien ne ressemblant à un motif d'expression régulière.

D'où l'idée simple d'ajouter des expressions régulières aux DTD et le nom DTD+RE.

Mais, cette approche ne respecte pas l'objectif 3 ayant servi à la conception de XML, c'est-à-dire :

  • XML doit être compatible avec SGML

Spécification

Seules trois productions de la grammaire de XML sont modifiées. Il s'agit de la production 46 (XML 3.2 Element Type Declaration) et des productions 55 et 56 (XML 3.3 Attribute-List Declaration). Elles sont modifiées comme suit :

 [46] contentspec    ::=  'EMPTY' | 'ANY' | Mixed | children | 'REGEX' S RegexType

 [55] StringType ::=  'CDATA' | RegexType

 [56] TokenizedType  ::=  'ID' | 'ID_REGEX' S RegexType | 'IDREF' | 'IDREFS'
       | 'ENTITY'| 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'

Les productions suivantes sont ajoutées :

  RegexType  ::=  '/' regex '/' RegexModifier ?

  RegexModifier  ::=  'i'

Un attribut de type 'ID_REGEX' doit respecter les mêmes contraintes de validité qu'un attribut de type 'ID'.

regex est une expression régulière étendue au sens de la définition des Extended Regular Expressions (ERE) définies par POSIX (volume Base Definitions, chapitre 9 - Regular Expressions). Les propriétés d'internationalisation définies par POSIX doivent être prises en compte.

Le caractère '/' servant de délimiteur doit être échappé par "\/" à l'intérieur d'une expression régulière. Et cet échappement doit être retiré avant de fournir l'expression au moteur d'expression régulière.

Traitement des entités

Toutes les références à des entités paramètres doivent être remplacées par leur valeur avant de fournir l'expression au moteur d'expression régulière.

 <!-- range [0..255] -->
 <!ENTITY % oct_dec "[0-1]?[0-9][0-9]?|2[0-4][0-9]|25[0-5]" > 
 <!ENTITY % ip_dec "%oct_dec\.%oct_dec\.%oct_dec\.%oct_dec" >
 <!ATTLIST mach ip /%ip_dec;/ >

L'utilisation d'entités paramètres permet de fractionner l'écriture d'expression régulière, ce qui a deux avantages :

  • augmenter la lisibilité des expressions régulières (ce qui a toujours été leur problème)
  • faciliter la réutilisation d'expression

Les entités prédéfinies de XML (&lt; &gt; &amp; &apos; et &quot;) ne doivent pas être utilisées à l'intérieur d'une expression régulière (et généralement à l'intérieur de la partie DTD). Les caractères < > & ' " doivent être utilisés directement.

En revanche, le caractère '%' doit être doublé à l'intérieur d'une expression régulière pour éviter la confusion avec le début d'une entité paramètre.

 <!ENTITY % pe "PE" >
 <!ATTLIST elt attr1 /%pe;/ >  <!-- regex: PE   -->
 <!ATTLIST elt attr2 /%%pe;/ > <!-- regex: %pe; -->
 <!ATTLIST elt attr3 /%%%pe;/ >    <!-- regex: %PE  -->

Ajouts implicites à l'expression régulière

Si xml:space='default', le préfixe "^[:space:]*" et le suffixe "[:space:]*$" sont concaténés à l'expression régulière. Si xml:space='preserve', le préfixe "^" et le suffixe "$" sont concaténés à l'expression régulière.

Il est inutile de spécifier explicitement une ancre dans une expression régulière. De plus, l'ancre "$" doit être comprise comme la fin de l'élément ou de la valeur d'un attribut et non comme une fin de ligne. Les caractères de fin de ligne peuvent être utilisés dans une expression régulière et sont reconnus par les expressions "." et "[:space:]".

Modificateur

La valeur 'i' permet de rendre l'expression régulière insensible à la casse.

 <!ELEMENT bool REGEX /(true|false)/i >

Entités paramètres prédéfinies

Ces entités correspondent à certains des types prédéfinis de W3C XML Schema Datatypes.

 <!ENTITY % re._boolean "(true|false|1|0)" >
 <!ENTITY % re.boolean "/%re._boolean;/" >
 <!ENTITY % re._integer "[+\-]?[:digit:]+" >
 <!ENTITY % re.integer "/%re._integer;/" >
 <!ENTITY % re._decimal "[+\-]?([:digit:]+(\.[:digit:]+)?|\.[:digit:]+)" >
 <!ENTITY % re.decimal "/%re._decimal;/" >
 <!ENTITY % re._float "%re._decimal;([Ee][+/-]?[:digit:]+)?" >
 <!ENTITY % re.float "/%re._float;/" >
 <!ENTITY % re._language "([:lower:]{2,3}(-[:upper:]{2})?|[ix]-.*)" >
 <!ENTITY % re.language "/%re._language;/" >
 <!ENTITY % re.__date "[:digit:]{4}-[:digit:]{2}-[:digit:]{2}" >
 <!ENTITY % re.__time "[:digit:]{2}:[:digit:]{2}:[:digit:]{2}" >
 <!ENTITY % re.__tz "Z|[+/-][:digit:]{2}:[:digit:]{2}" >
 <!ENTITY % re._datetime "%re.__date;T%re.__time;(%re.__tz;)?" >
 <!ENTITY % re.datetime "/%re._datetime;/" >
 <!ENTITY % re._date "%re.__date;(%re.__tz;)?" >
 <!ENTITY % re.date "/%re._date;/" >
 <!ENTITY % re._time "%re.__time;(%re.__tz;)?" >
 <!ENTITY % re.time "/%re._time;/" >
 <!-- URI : RFC2396 -->
 <!ENTITY % re.__escaped "%[:xdigit:]{2}" >
 <!ENTITY % re.__mark "[\-_\.!~\*'\(\)]" >
 <!ENTITY % re.__unreserved "([:alnum:]|%re.__mark;)" >
 <!ENTITY % re.__reserved "[;\/\?:@&=\+\$,]" >
 <!ENTITY % re.__uric "(%re.__reserved;|%re.__unreserved;|%re.__escaped;)" >
 <!ENTITY % re.__uric_no_slash "(%re.__unreserved;|%re.__escaped;|[;\?:@&=\+\$,])" >
 <!ENTITY % re.__pchar "(%re.__unreserved;|%re.__escaped;|[:@&=\+\$,])" >
 <!ENTITY % re.__param "%re.__pchar;*" >
 <!ENTITY % re.__segment "%re.__pchar;*(;%re.__param;)*" >
 <!ENTITY % re.__path_segments "%re.__segment;(\/%re.__segment;)*" >
 <!ENTITY % re.__abs_path "\/%re.__path_segments;" >
 <!ENTITY % re.__opaque_part "%re.__uric_no_slash;%re.__uric;*" >
 <!ENTITY % re.__path "(%re.__abs_path;|%re.__opaque_part;)" >
 <!ENTITY % re.__port "[:digit:]*" >
 <!ENTITY % re.__IPv4address "[:digit:]+\.[:digit:]+\.[:digit:]+\.[:digit:]+" >
 <!ENTITY % re.__toplabel "([:alpha:]|[:alpha:]([:alnum:]|-)*)[:alnum:]" >
 <!ENTITY % re.__domainlabel "([:alnum:]|[:alnum:]([:alnum:]|-)*)[:alnum:]" >
 <!ENTITY % re.__hostname "(%re.__domainlabel;\.)*%re.__toplabel;[\.]?" >
 <!ENTITY % re.__host "(%re.__hostname;|%re.__IPv4address;)" >
 <!ENTITY % re.__hostport "%re.__host;(:%re.__port;)?" >
 <!ENTITY % re.__userinfo "(%re.__unreserved;|%re.__escaped;|[;:&=\+\$,])*" >
 <!ENTITY % re.__server "((%re.__userinfo;@)?%re.__hostport;)?" >
 <!ENTITY % re.__reg_name "(%re.__unreserved;|%re.__escaped;|[\$,;:@&=\+])+" >
 <!ENTITY % re.__authority "(%re.__server;|%re.__reg_name;)+" >
 <!ENTITY % re.__scheme "[:alpha:]([:alnum:]|[\+\-\.])*" >
 <!ENTITY % re.__rel_segment "(%re.__unreserved;|%re.__escaped;|[;@&=\+\$,])+" >
 <!ENTITY % re.__rel_path "%re.__rel_segment;(%re.__abspath;)?" >
 <!ENTITY % re.__net_path "\/\/%re.__authority;(%re.__abspath;)?" >
 <!ENTITY % re.__query "%re.__uric;*" >
 <!ENTITY % re.__hier_part "(%re.__net_path;|%re.__abs_path;)(\?%re.__query;)?" >
 <!ENTITY % re.__absoluteURI "%re.__scheme;:(%re.__hier_part;|%re.__opaque_part;)" >
 <!ENTITY % re.__relativeURI 
          "(%re.__net_path;|%re.__abs_path;|%re.__rel_path;)(\?%re.__query;)?" >
 <!ENTITY % re.__fragment "%re.__uric;*" >
 <!ENTITY % re._uri "(%re.__absoluteURI;|%re.__relativeURI;)(#%re.__fragment;)?" >
 <!ENTITY % re.uri "/%re._uri;/" >

L'entité suivante doit permettre de rédiger des DTD compatibles avec des parseurs supportant ou non DTD+RE.

 <!ENTITY % xml-dtd-regex "INCLUDE" >

Exemple 1

Pour ce premier exemple, je vais réutiliser celui du livre 'XML Schema' de Eric van der Vlist. Voici l'instance de document :
  <library>
    <book id="b0836217462" available="true">
  <isbn>0836217462</isbn>
  <title xml:lang="en">Being a Dog Is a Full-Time Job</title>
  <author id="CMS">
    <name>Charles M Schulz</name>
    <born>1922-11-26</born>
    <dead>2000-02-12</dead>
  </author>
  <character id="PP">
    <name>Peppermint Patty</name>
    <born>1966-08-22</born>
    <qualification>bold, brash and tomboyish</qualification>
    </character>
  <character id="Snoopy">
    <name>Snoopy</name>
    <born>1950-10-04</born>
    <qualification>extroverted beagle</qualification>
  </character>
  <character id="Schroeder">
    <name>Schroeder</name>
    <born>1951-05-30</born>
    <qualification>brought classical music to the Peanuts strip</qualification>
  </character>
  <character id="Lucy">
    <name>Lucy</name>
    <born>1952-03-03</born>
    <qualification>bossy, crabby and selfish</qualification>
  </character>
    </book>
  </library>

Voici la DTD XML 1.0 :

 <!ELEMENT library (book+) >
 <!ELEMENT book (isbn, title, author+, character*) >
 <!ATTLIST book id ID #REQUIRED >
 <!ATTLIST book available (true|false) #REQUIRED >
 <!ELEMENT isbn (#PCDATA) >
 <!ELEMENT title (#PCDATA) >
 <!ATTLIST title xml:lang NMTOKEN #IMPLIED >
 <!ELEMENT author (name, born?, dead?) >
 <!ATTLIST author id ID #REQUIRED >
 <!ELEMENT name (#PCDATA) >
 <!ELEMENT born (#PCDATA) >
 <!ELEMENT dead (#PCDATA) >
 <!ELEMENT character (name, born?, dead?, qualification) >
 <!ATTLIST character id ID #REQUIRED >
 <!ELEMENT qualification (#PCDATA) >

Maintenant en utilisant DTD+RE :

 <!ENTITY % date "/[:digit:]{4}-[:digit:]{2}-[:digit:]{2}/" >
 <!ENTITY % _isbn "[:digit:]{10}" >
 <!ELEMENT library (book+) >
 <!ELEMENT book (isbn, title, author+, character*) >
 <!ATTLIST book id ID_REGEX /b%_isbn;/ #REQUIRED >
 <!ATTLIST book available %re.boolean; #REQUIRED >
 <!ELEMENT isbn REGEX /%_isbn;/ >
 <!ELEMENT title (#PCDATA) >
 <!ATTLIST title xml:lang %re.language; #IMPLIED >
 <!ELEMENT author (name, born?, dead?) >
 <!ATTLIST author id ID #REQUIRED >
 <!ELEMENT name (#PCDATA) >
 <!ELEMENT born REGEX %date; >
 <!ELEMENT dead REGEX %date; >
 <!ELEMENT character (name, born?, dead?, qualification) >
 <!ATTLIST character id ID #REQUIRED >
 <!ELEMENT qualification (#PCDATA) >

En supposant que ces deux DTD soient stockées respectivement dans les fichiers library.10.dtd et library.dre, il est possible de déclarer un point d'entrée commun entre un parseur DTD standard et un parseur DTD+RE de la façon suivante :

 <!ENTITY % xml-dtd-regex "IGNORE" >
 <![%xml-dtd-regex;[
 <!ENTITY % library.dtd   SYSTEM "library.dre" >
 ]]>
 <!ENTITY % library.dtd   SYSTEM "library.10.dtd" >
 %library.dtd;

Exemple 2

Pour ce deuxième exemple, je vais réutiliser de la documentation du module Perl PPM::XML::PPD qui décrit une application XML de Perl Package Distribution. Voici l'instance de document :
 <SOFTPKG NAME="Math-MatrixBool" VERSION="4,2,0,0">
 <TITLE>Math-MatrixBool</TITLE>
 <ABSTRACT>Easy manipulation of matrices of booleans (Boolean Algebra)</ABSTRACT>
 <AUTHOR>Steffen Beyer (sb@sdm.de)</AUTHOR>
 <LICENSE HREF="http://www.ActiveState.com/packages/Math-MatrixBool/license.html" />
 <IMPLEMENTATION>
  <OS VALUE="WinNT" />
  <OS VALUE="Win95" />
  <PROCESSOR VALUE="x86" />
  <CODEBASE 
  HREF="http://www.ActiveState.com/packages/Math-MatrixBool/Math-MatrixBool-4.2-bin-1-Win32.tar.gz" />
  <DEPENDENCY NAME="Bit-Vector" />
  <INSTALL>
  </INSTALL>
  <UNINSTALL>
  </UNINSTALL>
 </IMPLEMENTATION>

 <IMPLEMENTATION>
  <DEPENDENCY NAME="Bit-Vector" />
  <CODEBASE 
  HREF="http://www.cpan.org/CPAN/modules/by-module/Math/Math-MatrixBool-4.2.tar.gz" />
  <INSTALL>
     system("make"); ;;
     system("make test"); ;;
     system("make install"); ;;
  </INSTALL>
 </IMPLEMENTATION>
 </SOFTPKG>

Voici la DTD XML 1.0 (cette version commentée en HTML a été générée par le module Perl dtd2html) :

 <!ELEMENT SOFTPKG   (ABSTRACT | AUTHOR | IMPLEMENTATION | LICENSE | TITLE)*>
 <!ATTLIST SOFTPKG   NAME CDATA #REQUIRED>
 <!ATTLIST SOFTPKG   VERSION  CDATA #IMPLIED>
 <!ELEMENT TITLE (#PCDATA)>
 <!ELEMENT ABSTRACT  (#PCDATA)>
 <!ELEMENT AUTHOR    (#PCDATA)>
 <!ELEMENT LICENSE   EMPTY>
 <!ATTLIST LICENSE   HREF CDATA #REQUIRED>
 <!ELEMENT IMPLEMENTATION    (CODEBASE | DEPENDENCY | LANGUAGE | OS |
      OSVERSION | PERLCORE | PROCESSOR | INSTALL |
      UNINSTALL )*  >
 <!ELEMENT CODEBASE  EMPTY>
 <!ATTLIST CODEBASE  FILENAME CDATA #IMPLIED>
 <!ATTLIST CODEBASE  HREF CDATA #REQUIRED>
 <!ELEMENT DEPENDENCY EMPTY>
 <!ATTLIST DEPENDENCY VERSION CDATA #IMPLIED>
 <!ATTLIST DEPENDENCY NAME    CDATA #REQUIRED>
 <!ELEMENT LANGUAGE  EMPTY>
 <!ATTLIST LANGUAGE  VALUE    CDATA #REQUIRED>
 <!ELEMENT OS    EMPTY>
 <!ATTLIST OS    VALUE    CDATA #REQUIRED>
 <!ELEMENT OSVERSION EMPTY>
 <!ATTLIST OSVERSION VALUE    CDATA #REQUIRED>
 <!ELEMENT PERLCORE  EMPTY>
 <!ATTLIST PERLCORE  VERSION  CDATA #REQUIRED>
 <!ELEMENT PROCESSOR EMPTY>
 <!ATTLIST PROCESSOR VALUE    CDATA #REQUIRED>
 <!ELEMENT INSTALL   (#PCDATA)>
 <!ATTLIST INSTALL   HREF CDATA #IMPLIED>
 <!ATTLIST INSTALL   EXEC CDATA #IMPLIED>
 <!ELEMENT UNINSTALL (#PCDATA)>
 <!ATTLIST UNINSTALL HREF CDATA #IMPLIED>
 <!ATTLIST UNINSTALL EXEC CDATA #IMPLIED>

Maintenant en utilisant DTD+RE :

 <!ENTITY % ppd.name "/([:alnum:]|[\-_])+/" >
 <!ENTITY % ppd.version "/[:digit:]+(,[:digit:]+){3}/" >
 <!ELEMENT SOFTPKG   (ABSTRACT | AUTHOR | IMPLEMENTATION | LICENSE | TITLE)*>
 <!ATTLIST SOFTPKG   NAME %ppd.name; #REQUIRED>
 <!ATTLIST SOFTPKG   VERSION  %ppd.version; #IMPLIED>
 <!ELEMENT TITLE REGEX    %ppd.name; >
 <!ELEMENT ABSTRACT  (#PCDATA)>
 <!ELEMENT AUTHOR    (#PCDATA)>
 <!ELEMENT LICENSE   EMPTY>
 <!ATTLIST LICENSE   HREF %re.uri; #REQUIRED>
 <!ELEMENT IMPLEMENTATION    (CODEBASE | DEPENDENCY | LANGUAGE | OS |
      OSVERSION | PERLCORE | PROCESSOR | INSTALL |
      UNINSTALL )*  >
 <!ELEMENT CODEBASE  EMPTY>
 <!ATTLIST CODEBASE  FILENAME CDATA #IMPLIED>
 <!ATTLIST CODEBASE  HREF %re.uri; #REQUIRED>
 <!ELEMENT DEPENDENCY EMPTY>
 <!ATTLIST DEPENDENCY VERSION %ppd.version; #IMPLIED>
 <!ATTLIST DEPENDENCY NAME    %ppd.name; #REQUIRED>
 <!ELEMENT LANGUAGE  EMPTY>
 <!ATTLIST LANGUAGE  VALUE    CDATA #REQUIRED>
 <!ELEMENT OS    EMPTY>
 <!ATTLIST OS    VALUE    CDATA #REQUIRED>
 <!ELEMENT OSVERSION EMPTY>
 <!ATTLIST OSVERSION VALUE    %ppd.version; #REQUIRED>
 <!ELEMENT PERLCORE  EMPTY>
 <!ATTLIST PERLCORE  VERSION  %ppd.version; #REQUIRED>
 <!ELEMENT PROCESSOR EMPTY>
 <!ATTLIST PROCESSOR VALUE    CDATA #REQUIRED>
 <!ELEMENT INSTALL   (#PCDATA)>
 <!ATTLIST INSTALL   HREF %re.uri; #IMPLIED>
 <!ATTLIST INSTALL   EXEC CDATA #IMPLIED>
 <!ELEMENT UNINSTALL (#PCDATA)>
 <!ATTLIST UNINSTALL HREF %re.uri; #IMPLIED>
 <!ATTLIST UNINSTALL EXEC CDATA #IMPLIED>

Exemple 3

Ce troisième exemple concerne XHTML et plus particulièrement XHTML 1.1 qui est la version modularisée. Cette version va me faciliter le travail. En effet, il suffit uniquement de réécrire un module pour commencer à profiter des avantages de DTD+RE. Il s'agit du fichier xhtml-datatypes-1.mod qui spécifie des types d'attribut en utilisant "CDATA", "NMTOKEN" et "NMTOKENS". Les expressions régulières suivantes sont des versions naïves, mon objectif n'est pas ici de donner les meilleures expressions régulières mais seulement de montrer les avantages de cette technique. De plus, si on veut appliquer la règle :

soyez tolérant à propos de ce que vous acceptez et strict dans ce que vous produisez

Il sera peut-être utile de définir deux versions suivant le coté où l'on se place.

 <!-- Datatypes

 defines containers for the following datatypes, many of
 these imported from other specifications and standards.
 -->

 <!-- Length defined for cellpadding/cellspacing -->

 <!-- nn for pixels or nn% for percentage length -->


 <!ENTITY % Length.datatype "/[:digit:]+%?/" >

 <!-- space-separated list of link types -->


 <!ENTITY % LinkTypes.re "(next|prev|head|toc|parent|child|index|glossary)" >
 <!ENTITY % LinkTypes.datatype "/%LinkTypes.re;([:space:]+%LinkTypes.re;)*/" >

 <!-- single or comma-separated list of media descriptors -->


 <!ENTITY % MediaDesc.re "(screen|tty|tv|projection|handheld|print|braille|aural|all)" >
 <!ENTITY % MediaDesc.datatype "/%MediaDesc.re;(,%MediaDesc.re;)*/" >

 <!-- pixel, percentage, or relative -->


 <!ENTITY % MultiLength.datatype "/[:digit:]+%?/" >

 <!-- one or more digits (NUMBER) -->


 <!ENTITY % Length.datatype "/[:digit:]+/" >

 <!-- integer representing length in pixels -->


 <!ENTITY % Pixels.datatype "/\+?[:digit:]+/" >

 <!-- script expression -->
 <!ENTITY % Script.datatype "CDATA" >

 <!-- textual content -->
 <!ENTITY % Text.datatype "CDATA" >

 <!-- Imported Datatypes ................................ -->

 <!-- a single character from [ISO10646] -->


 <!ENTITY % Character.datatype "/./" >

 <!-- a character encoding, as per [RFC2045] -->


 <!ENTITY % Charset.re "([\.\-_:]|[:alnum:])+" >
 <!ENTITY % Charset.datatype "/%Charset.re;/" >

 <!-- a space separated list of character encodings, as per [RFC2045] -->


 <!ENTITY % Charsets.datatype "/%Charset.re;(,%Charset.re;)*/" >

 <!-- Color specification using color name or sRGB (#RRGGBB) values -->


 <!ENTITY % Color.datatype "/([:alpha:][:alnum:]*|#[:xdigit:]{6})/" >

 <!-- media type, as per [RFC2045] -->


 <!ENTITY % ContentType.re.type "([:alnum:]|-)+" >
 <!ENTITY % ContentType.re.subtype "([:alnum:]|-)+" >
 <!ENTITY % ContentType.re.parameter "[^=]+=[^;]+" >
 <!ENTITY % ContentType.re 
   "%ContentType.re.type;\/%ContentType.re.subtype;(;%ContentType.re.parameter;)*" >
 <!ENTITY % ContentType.datatype "/%ContentType.re;/" >

 <!-- comma-separated list of media types, as per [RFC2045] -->


 <!ENTITY % ContentTypes.datatype "/%ContentType.re;(,%ContentType.re;)*/" >

 <!-- date and time information. ISO date format -->


 <!ENTITY % Datetime.datatype "/%re._datetime;/" >

 <!-- formal public identifier, as per [ISO8879] -->


 <!ENTITY % FPI.datatype "CDATA" >

 <!-- a language code, as per [RFC3066] -->


 <!ENTITY % LanguageCode.datatype "/%re._language;/" >

 <!-- a Uniform Resource Identifier, see [URI] -->


 <!ENTITY % URI.datatype "/%re._uri;/" >

 <!-- a space-separated list of Uniform Resource Identifiers, see [URI] -->


 <!ENTITY % URIs.datatype "/%re._uri;([:space:]+%re._uri;)*/" >

Ce n'est certainement pas la meilleure utilisation de DTD+RE possible, mais c'est un début par rapport au riche existant concernant XHTML.

Conclusion

DTD+RE est basé sur une idée simple. Cela doit permettre :

  • de faciliter l'implantation d'un parseur à partir d'un parseur validant de DTD, en effet des moteurs d'expression sont disponibles dans les langages qui sont utilisés pour écrire des parseurs (Java, C, ...)
  • de faciliter l'apprentissage, en effet il n'y a pas là de nouvelles technologies nécessitant d'épaisse documentation

De plus, la technique des expressions régulières est bien connue et a largement fait ses preuves dans le domaine du traitement des chaînes de caractères.

Les techniques de modularisation des DTD permettent d'obtenir une réutilisation de macro-composants, comme pour XHTMLMOD. L'utilisation d'entités paramètres pour des fragments d'expression régulière permettra une réutilisation de micro-composants. Cette réutilisation commence par la liste d'entités paramètres prédéfinies qui devra être affinée et enrichie.

L'intérêt majeur de cette approche est de proposer une compatibilité ascendante, une DTD XML 1.0 est une DTD+RE. Cela permet la migration d'application en enrichissant progressivement des DTD avec des expressions régulières.

Références

[RELAX NG]
REgular LAnguage description for XML - Next Generation See: http://www.oasis-open.org/committees/relax-ng/
[POSIX]
Portable Operating System Interface (POSIX), IEEE Std 1003.1-2001 See: http://www.unix.org/version3/ieee_std.html
[SGML]
Standard Generalized Markup Language, ISO 8879:1986
[WXS]
XML Schema Part 2: Datatypes, W3C Recommendation. See: http://www.w3.org/TR/2001/REC-xmlschema-2-20010502
[XHTML]
Module-based XHTML, W3C Recommendation. See: http://www.w3.org/TR/2001/REC-xhtml11-20010531
[XHTMLMOD]
Modularization of XHTML, W3C Recommendation. See: http://www.w3.org/TR/2001/REC-xhtml-modularization-20010410
[XML]
Extensible Markup Language (XML) 1.0 (Second Edition), W3C Recommendation. See: http://www.w3.org/TR/2000/REC-xml-20001006

Copyright 2003, François Perrad.


 

Mots clés.



L'histoire de XML s'écrit en ce moment même. XMLfr vous aide à la suivre et à en dégager les tendances.


Les documents publiés sur ce site le sont sous licence "Open Content"
Conception graphique
  l.henriot  

Conception, réalisation et hébergement
Questions ou commentaires
  redacteurs@xmlfr.org