Google Chercher dans diml.org
[ english ]

Table des matières
1. Motivation
2. Définitions
3. Définition de la passerelle d'injection
3.1 L'appel de document XML
3.2 Limitations fonctionnelles de la passerelle
4. Translation d'identifiants XML
4.1 L'espace de noms du DIML
4.1.1 Les règles de l'espace de noms DIML
4.1.2 Les portées de noms standard du DIML
4.1.3 Contraintes de translation
4.2 Construction du nom
4.2.1 Identification d'élément
4.2.2 L'identification de fichier source
4.3 Forme générale des identifiants provenant d'XML
4.3.1 Forme développée
4.3.2 Exemples de formes développées
4.3.3 Formes réduites
5. L'instruction %xml
5.1 Forme générale
5.2 L'attribut source
5.3 L'attribut scope
5.4 L'attribut select
5.4.1 Forme générale du sélecteur
5.4.2 Sélection d'un élement unique
5.4.3 Sélection de références d'éléments XML
5.4.4 Sélection d'attributs d'éléments XML
5.4.5 L'attribut virtuel innerText
5.4.6 L'attribut virtuel innerXml
5.4.7 L'attribut virtuel innerHtml
5.4.8 L'utilisation de motifs comme sélecteur d'élément
5.4.9 L'utilisation du super-méta '**'
5.5 L'attribut alias
5.6 L'attribut nobr
5.7 L'attribut flat
A. Appendices
Appendice 2 : Références
Appendice 3 : Remerciements
6 Exemples
6.1 Sélections à résolution unique
6.1.1 Elément complètement discriminé
6.1.2 Contenu complètement discriminé
6.1.3 Attribut d'élément discriminé
6.2 Sélections à résultat multiple
6.2.1 Elément sans discriminant
6.2.2 Attribut sur un élément non discriminé
 Dernières infos
 Une application du composant  WCT_NEWS  
>> Haut de la page

Data Injection Markup Language

Prise en charge de sources de données XML

Auteur : V.G. FREMAUX
E.I.S.T.I. / Cergy, France
Laboratoire de Recherche Appliquée
Nouvelles Technologies de l'Information et de la Communication

Version : 1.0 / Janvier 2002

>0. Objet de ce document

Ce projet de spécification est le résultat d'un travail effectué dans le cadre des recherches appliquées de l'Ecole Internationale des Sciences du Traitement de l'Information de Cergy (France), en vue de la mise en place du Laboratoire des Nouvelles Technologies de l'Information et la Communication. Nous ne savons pas, au moment de son écriture, l'issue possible pour cette spécification, son usage futur, ni même si elle sera publiée officiellement un jour.

Cependant nous essayons de la rédiger et de joindre le maximum de documentation dans cette éventualité.

1. Motivation

La présente spécification définit une stratégie d'alimentation de documents DIML par du contenu au format XML.

Le codage d'un document électronique dynamique, indépendamment de sa forme de publication, est divisé en quatre sous-ensembles syntaxiques :

  • La construction procédurale (process) rassemblant les ressources et les données nécessaires à la production du document.
  • La forme, aujourd'hui efficacement condensé par les différents langages de feuilles de style, qu'ils soient basés sur des cascades de propriétés (CSS), ou sur des filtres de transformation (XSL).
  • La mise en page, ou structure, qui détermine le placement, le colonnage, la disposition et induit une hiérarchie implicite de dépendance entre les différentes séquences de contenus (in-line sequences).
  • Le contenu proprement dit, généralement sous forme de séquences de caractères litéraux, dans un jeu de caractères défini.

Si le DIML optimise correctement les structures, en permettant une réutilisabilité maximale des séquences de code les exprimant, et permet une dissociation forte entre document et process, il n'est est pas de même concernant contenu et structure. En effet, une intervention portant sur une petite partie du contenu nécessitera des efforts préalable pour la retrouver au milieu des balises et des attributs HTML.

Si au début de l'étude du DIML, nous pensions pouvoir proposer une alternative complète au XML, force est de constater que le XML a un grand intérêt combiné au DIML. En effet, le XML par construction, offre une expression très sobre d'un contenu sémantique, dépouillé de toute mise en forme ou structure. Cette construction élémentaire se bornant à définir les différentes phrases ou sections de contenu, et à les identifier d'une manière unique, permet de les extraire et les traiter unitairement. C'est ce minimalisme possible de la syntaxe XML qui, pris en charge par le processeur DIML, peut fournir une forme native suffisante et exploitable à des masses documentaires importantes et standardisées.

2. Définitions

XML
"eXtended Markup Language", une norme de balisage qui décrit les règles de déclaration et de construction de documents.

3. Description de la passerelle d'injection

3.1 L'appel de document XML

La passerelle d'injection XML permet au processeur ESSI d'avoir accès à des éléments d'un fichier XML. Un appel XML translate tout ou partie des éléments XML du document cible vers des variables DIML. Elles sont alors utilisables comme n'importe quelle variable DIML.

Dans un document construit dynamiquement, on distingue les données issues d'une base de données ou toute autre source de données dynamiques de l'ensemble des informations nécessaires à l'habillage. La passerelle est surtout utile pour l'extraction de ces dernières à partir de descriptions statiques écrites en XML. Cette dissociation permet, par exemple, de prévoir un certain nombre d'emplacements pour du rédactionnel, du texte d'aide et d'assistance, des textes multilingues, et de pouvoir préparer l'encodage des pages. La rédaction pourra s'effectuer indépendamment. Ces éléments de contenus, une fois finalisés et formatés en XML, prennent naturellement leur place dans le document final.

Par exemple, considérons l'écran d'un tableau de bord qui affiche une pseudo-boite de dialogue en présence d'une erreur :

<%if ((%FORM::what% ne "documentation") 
	and (%FORM::what% ne "demos") 
		and (%AUTH::OK% ne "1")) %>
<DIV ID="resultat_membre_shadow" 
	STYLE="position : absolute ; 
	       display : block ; 
          width : 450px ; 
          height : 200px ; 
          top : 143px ; 
          left : 203px ; 
          background-color : 
          rgb(69,77,94)"></DIV>
<DIV ID="resultat_membre" 
   STYLE="position : absolute ; 
          display : block ; 
          width : 450px ; 
          height : 200px ; 
          top : 140px ; 
          left : 200px ; 
          background-color : 
          rgb(200,0,0) ; 
          text-align : center ; 
          vertical-align : middle">
<TABLE WIDTH=90% BORDER=0 CELLSPACING=5 CELLPADDING=0>
<TR><TD ALIGN=right COLSPAN=2>
</TD></TR>
<TR>
<TD VALIGN=top>
   <P CLASS="error"><B>Erreur d'authentification.</B> 
<P CLASS="error">Votre identifiant ou votre mot 
   de passe est erroné. Vous ne pouvez entrer dans 
   cette zone de téléchargement.
<P CLASS="error"><A 
   HREF="Javascript:history.back()" 
   CLASS="error">Accueil téléchargement</A>
</TD>
</TR>
</TABLE>
</DIV>
<%endif %>

Erreur d'authentification.

Votre identifiant ou votre mot de passe est erroné. Vous ne pouvez entrer dans cette zone de téléchargement.

Accueil téléchargement

Ici, seules trois phrases concernent la rédaction du message :

  • Erreur d'authentification.
  • Votre identifiant ou votre mot de passe est erroné. Vous ne pouvez entrer dans cette zone de téléchargement.
  • Accueil téléchargement.

Le reste du code est soit affaire de structure (la notion de DIV, le placement, la syntaxe conditionnelle DIML, etc.), ou de forme (les classes , les attributs STYLE etc.). Ici, la séquence d'exemple ne contient pas d'encodage significatif d'une construction dynamique.

La passerelle XML du DIML permet de déplacer ces trois phrases dans un document XML, et au DIML de les récupérer pour les injecter dans la carcasse DIML.

L'exemple peut ainsi être dissocié en un document XML :

<?xml version="xml1.0" ?>
<ERREUR>
	<TITRE>Erreur d'authentification</TITRE>
	<TEXTE>Votre identifiant ou votre mot de passe est 
   erroné. Vous ne pouvez entrer dans cette zone de 
   téléchargement.</TEXTE>
	<TEXTE_LIEN>Accueil téléchargement</TEXTE_LIEN>
</ERREUR>

et une carcasse d'injection DIML

<%if ((%FORM::what% ne "documentation") and (%FORM::what% ne "demos") 
and (%AUTH::OK% ne "1")) %>
<DIV ID="resultat_membre_shadow" STYLE="position : absolute ; 
                                           display : block ; 
                                           width : 450px ; 
                                           height : 200px ; 
                                           top : 143px ; 
                                           left : 203px ; 
                                           background-color : 
                                           rgb(69,77,94)"></DIV>
<DIV ID="resultat_membre" STYLE="position : absolute ; 
                                    display : block ; 
                                    width : 450px ; 
                                    height : 200px ; 
                                    top : 140px ; 
                                    left : 200px ; 
                                    background-color : rgb(200,0,0) ; 
                                    text-align : center ; 
                                    vertical-align : middle">
<TABLE WIDTH=90% BORDER=0 CELLSPACING=5 CELLPADDING=0>
<TR><TD ALIGN=right COLSPAN=2>
</TD></TR>
<TR>
<TD VALIGN=top><P CLASS="error"><B><%%ERREUR::TITRE%%></B> 
<P CLASS="error"><%%ERREUR::TEXTE%%>
<P CLASS="error">
<A HREF="Javascript:history.back()" CLASS="error"><%%ERREUR::TEXTE_LIEN%%></A>
</TD>
</TR>
</TABLE> 
</DIV>
<%endif %>

La passerelle XML du DIML doit donc :

  • Reconnaître les différents éléments d'un document XML, en en différenciant les instances.
  • Sélectionner un sous-ensemble de ces éléments.
  • Convertir les identités XML de ces éléments en variables DIML.
  • Assumer plusieurs ouvertures du même document XML dans un même processus.
  • Assumer l'ouverture de plusieurs documents XML de DTD identique dans un même processus, en gérant les éventuels conflits de noms.
  • Reconnaitre l'espace de nom HTML (xmlns:html) et traiter le contenu HTML comme du contenu litéral.

3.2 Limitations fonctionnelles de la passerelle

En aucun cas, la passerelle ne peut prendre le rôle d'un vérificateur de document. La conformité à une DTD est une opération trop coûteuse au moment de la publication pour pouvoir être assurée dynamiquement. Les documents sont donc considérés comme "bien formés" au sens XML large, et seuls la forme entité/attributs est considérée.

La passerelle ignorera tout référence de style XSL, car sa vocation n'est pas non plus d'être un moteur XSL.

Les éléments XML peuvent contenir :

  • Des séquences #CDTATA (texte litéral).
  • Du HTML, qui DOIT être isolé dans l'espace de noms xmlns:html.
  • Du Javascript intégré dans les balises <html:SCRIPT>...<html:/SCRIPT>.
  • Des entités caractères SGML.
  • Des instructions DIML, traitées récursivement lors de l'appel de la variable DIML translatée.

4. Translation d'identifiants XML

4.1 L'espace de noms du DIML

4.1.1 Les règles de l'espace de noms DIML

Le DIML laisse libre la définition et l'organisation d'un espace de noms de variables en autorisant les caractères étendus dans la constitution des tokens. En effet, la délimitation d'une variable, marquée par l'encadrement %...% permet l'usage de ce jeu étendu. Des variables aussi différentes que :

  1. <%%VARIABLE%%>
  2. <%%FONCTION()%%>
  3. <%%VARIABLE1->VARIABLE2%%>
  4. <%%PORTEE::VARIABLE%%>
  5. <%%PORTEE::SOUS_PORTEE::VARIABLE%%>

, pour les plus fréquentes, sont utilisables.

Cette liberté syntaxique peut être utilisée pour marquer des pseudo-comportements ou sémantiques de variables. Par exemple, dans les exemples précédents :

  • (1) Une variable simple,
  • (2) une sémantique de fonction à valeur de retour, par exemple, un formulaire effectuant un appel CGI,
  • (3) une champ d'une portée sémantique de type structure,
  • (4-5) une variable entièrement déterminée par une portée.

De nombreuses autres formes sémantiques sont possibles par le jeu des symboles, tant que l'unicité du terme constituant le nom de variable est préservé.

Dans tous les cas, les formes d'identifiant adoptées n'ont aucune signification particulière au vu du processeur ESSI. Leur sémantique reste sous la responsabilité du développeur..

4.1.2 Les portées de noms standard du DIML

La spécification 1.0 du DIML définit quelques portées typiques implémentées dans les premières versions du processeur ESSI.

Dès la version 1.0 du moteur ESSI :

<%%ENV::variable_suffix%%>
Portée liée à toutes les variables d'environnement de l'instance de moteur en cours d'exécution. Cet environnement est en général abondé de toutes les variables d'interface CGI [CGI].

<%%CGI::variable_suffix%%>
Portée spécifique aux variables créées par le serveur HTTP au compte de l'interface CGI. On utilisera avantageusement la portée ENV::. Implémentée à partir de la version 2.5 du moteur ESSI.

<%%FORM::variable_suffix%%>
Portée des variables créées par décodage de la chaîne de paramêtres CGI.

Les portées utilisateur
Toute portée explicite obtenue par l'utilisation de noms intégrant au moins une fois la séquence de portée ::, qu'elle ait ou non un sens.

La portée de base
Tout autre nom n'utilisant pas la séquence de portée ::.

La version 2.1 du moteur ESSI introduit la nouvelle portée :

<%%FILE::variable_suffix%%>
Portée des variables issues du décodage d'un "upload" de fichier via une transmission de type MIME "form-data/multipart" [MIME1].
4.1.3 Contraintes de translation

L'intégration d'éléments XML dans une carcasse DIML suppose qu'ils soient translatés dans une portée de noms qui lui soit accessible. La construction d'une telle portée nécessite l'identification de certaines contraintes :

  • La portée XML doit prévenir tout risque de collision avec les autres portées, qu'elles soient standard ou utilisateur (la définition d'une portée explicite élimine d'office le risque de collision avec les autres portées).
  • La portée XML doit éviter tout risque de collision avec d'autres portées issues du XML.
  • La translation doit être indépendante de la DTD.
  • La translation ne doit pas imposer de règles particulières à la DTD.
  • La translation doit tenir compte de la présence d'instances multiples du même élément.
  • La translation s'appuie sur la DTD qui n'est qu'un modèle. Elle doit par conséquent prendre à sa charge l'identification de l'instance de document.
  • La translation doit produire des noms lisibles, et facilement utilisable dans le flux DIML d'accueil. Des noms résolus sur trois lignes de texte seraient inappropriés.
  • La translation doit déterminer des règles de calcul des valeurs des variables suivant que l'élément est terminal ou non.

4.2 Construction du nom DIML

4.2.1 Identification d'élément

L'injection d'éléments XML suppose l'ouverture d'un fichier, dans lequel l'élément est identifiable par extraction textuelle. L'analyse de l'identification XML s'effectue en trois étapes :

  1. L'élément se situe à un certain endroit de l'arbre hiérarchique du le contenu. Il doit être qualifié dans la portée du fichier par un chemin d'accès :

    Par exemple, dans le fichier /home/diml/xml/xmlsample.xml :

    <?xml version="xml1.0" ?>
    <root>
       <box>
          <box>
             <element>sample1</element>
          </box>
       </box>
    </root>
    

    la chaîne "sample1" est la valeur d'un élément qualifié par la clef :

    /home/diml/xml/xmlsample.xml#root.box.box.element.value

    Cette qualification très incomplète est insuffisante pour pouvoir traiter le cas général. Elle suppose en effet l'unicité d'une telle clé, confondant le typage de l'élément avec son identification. Ainsi, elle ne peut répondre au fichier XML :

    <?xml version="xml1.0" ?>
    <root>
       <box>
          <box>
             <element>sample1</element>
          </box>
       </box>
       <box>
          <box>
             <element>sample2</element>
          </box>
       </box>
    </root>
    

    , même si ce fichier est "bien formé" sur la DTD :

    <!ELEMENT root (box+)>
    <!ELEMENT box (box+ | element)>
    <!ELEMENT element (#PCDATA)>
    
  2. En cas d'instances multiples, une discrimination des positions des nœuds dans l'arbre (chemin d'accès à l'information) est donc nécessaire. Le nom d'élément ayant principalement une valeur de type, seule l'utilisation d'un attribut XML discriminant permet de résoudre ce chemin d'accès. Le fichier source DOIT donc être transformé ansi:

    <?xml version="xml1.0" ?>
    <root>
       <box id="1">
          <box>
             <element>sample1</element>
          </box>
       </box>
       <box id="2">
          <box>
             <element attr1=attrvalue1>sample2</element>
          </box>
       </box>
    </root>
    

    L'ajout de l'identifiant n'est nécessaire que pour les éléments à fils multiples (modificateurs d'occurences * ou +). Dans le cas précédent, la clef inspirée des patterns XSL :

    root.box(@id=='2').box.element.value

    nous conduit à la chaîne "sample2".

    Quand l'injection d'une valeur d'attribut particulière est nécessaire, on écrira :

    root.box(@id=='2').box.element.attr1

    En cas d'absence d'identifiant, on aura recours au méta-attribut ordinal @@, indexé sur l'ordre d'apparition d'un élément dans le fichier source, et de portée réduite à l'élément de rang immédiatement supérieur (numérotation par nœuds). Par exemple :

    root.box(@@=='2').box.element.attr1

    signifie l'attribut attr1 de l'élément element de la boîte box de la troisième boîte box aparaissant dans root, c'est à dire dans le document.

  3. Enfin, si plusieurs fichiers appuyés sur la même DTD sont ouverts, les jeux de variables extraits doivent rester indépendants. Ainsi dans le cas de l'injection de la valeur d'élément root.box(@id=='2').box.element.innerText des fichiers xmlsample.xml et xmlsample2.xml, les identifiants devront comporter une partie discriminante par rapport à la source.
4.2.2 Identification de fichier source

D'un point de vue théorique, l'identification du fichier source devrait reposer sur une URI, et devrait dans ce cas conduire à des définitions de clef d'accès aux données du type :

/home/diml/xml/xmlsample.xml#root.box(@id=='2').box.element.innerText

ou encore, si ce fichier est accessible sur un plan réseau :

http://www.diml.net/xml/xmlsample.xml#root.box(@id=='2').box.element.innerText

D'un point de vue pratique, la manipulation de références complètes n'est pas souhaitable, car elle diminue d'autant l'intérêt du métabalisage du HTML qui, rappelons-le, est motivé par la conservation d'une bonne lisibilité du source.

C'est pourquoi l'identification de la source, indispensable dans le cas d'ouverture de fichiers XML multiples sur des DTD identiques ou redondantes, est résolue dans la translation XML->DIML par une indirection, définie au moment de la prise en compte du fichier (voir les attributs scope et alias).

4.3 Forme générale des identifiants provenant d'XML

4.3.1 Forme développée

Les identifiants produits lors de la translation sont accessibles comme des variables DIML standard, selon le schéma :

<%%scope_id::XML_tree_identifier%%>

Dans lequel scope_id est l'identifiant de portée tel que défini par l'attribut scope de l'instruction %xml et XML_tree_identifier est la clef hiérachique d'accès à la variable sous la forme Bakkus-Naur suivante :

XML_tree_identifier ::= [ *[ node_id "." ] XML_tree_identifier ] | node_id
node_id             ::= element_id ?[ "[" node_count "]" ]
element_id          ::= #NMTOKEN
node_count          ::= integer
integer             ::= digit *[ digit ]
digit               ::= 0|1|2|3|4|5|6|7|8|9

Tous les nœeuds sont indexés par la valeur de l'attribut implicite ordinal @@.

Note : Le sélecteur ordinal @@ compte l'ordre d'apparition de l'élément dans la portée de l'élément père. Il vaut donc toujours 0 pour le premier élément de chaque type composant le contenu de son père.

4.3.2 Exemples de formes développées

Considérons le fichier XML suivant :

<?xml version="xml1.0" ?>
<root>
   <box id="1">
      <box>
         du contenu de box.box
         <element attrib1="value1" attrib2="value2">sample a</element>
         <element attrib2="value2" attrib1="value2">sample b</element>
      </box>
   </box>
   <box id="2">
      <box>
         <element attrib1="value1">sample2</element>
         <souselement>subsample1</element>
         <souselement>subsample2</element>
         <souselement>subsample3</element>
         <souselement>subsample4</element>
      </box>
   </box>
</root>

Les syntaxes suivantes de clefs d'accès complètes sont valides :

<%%SAMP1::root[0].box[0].box[0].element[0].innerText%%>
Une telle clef pointe la valeur "sample a", comme valeur textuelle du premier element de la première box (3 ème niveau de hiérarchie) de la première box (2ème niveau de hiérarchie) de l'élément racine root, le tout redirigé vers la portée SAMP1.
<%%SAMP1::root[0].box[0].box[0].element[0].attrib2%%>
Une telle clef pointe la valeur "value2", comme valeur de l'attribut attrib2 du premier element de la première box (3 ème niveau de hiérarchie) de la première box (2ème niveau de hiérarchie) de l'élément racine root, le tout redirigé vers la portée SAMP1.
4.3.3 Formes réduites

La nécessité de formes réduites apparaît lors de la récupération de valeurs dans des documents issus d'une pratique bureautique, bien plus complexes que la synthèse de "fiches" de données dans lesquelles la DTD reste peu développée.

La complexité des documents "humains" rend inefficace l'utilisation de la forme développée, car la complexité de l'arbre d'éléments est souvent trop grande, et conduit à l'identification de contenus inscrits assez profondément dans l'arbre hiérarchique. Les formes réduites des identifiants translatés permettent, dans une certaine mesure, d'extraire des données dans ce contexte, sans pour autant alourdir considérablement la syntaxe du source de la carcasse DIML.

5 L'instruction %xml

5.1 Forme générale

L'intégration de variables provenant d'une extraction XML demande un appel préalable qui décrit et programme l'extraction de données du fichier, et résultant en la mise à disposition des variables translatées.

Cet appel est une nouvelle instruction DIML de forme générale :

<%xml
    source="filename"
    scope="variable_scope"
    select="XML_selector"
    alias="alias_prefix"
    noHtml
    noXml
    noText
    flat %>

Voici un exemple d'appel à un fichier XML local :

<%xml source="../xml/xmlsample.xml" scope="SAMP1" select="box(@id=~'valid')" %>

5.2 L'attribut source

L'attribut source spécifie le fichier xml source. Il doit contenir une adresse physique absolue ou relative selon le standard du système d'exploitation support.

Exemples :

<%xml source="../xml/sample.xml"   -> adresse relative
<%xml source="&lt;%%XML_ROOT_PATH%%&gt;../xml/sample.xml" 
	-> adresse relative à indirection DIML
<%xml source="D:/dimlweb/xml/sample.xml"  -> adresse absolue sous Windows
<%xml source="/home/www/dimlweb/xml/sample.xml"  -> adresse absolue sous Unix

5.3 L'attribut scope

L'attribut scope détermine le plan de portée adopté des variables produites par l'appel. Cette portée peut être n'importe quel nom de variable DIML utilisant tous les caractères sauf %, [, ], *, '\n' et '\r'.

Note : des noms de portée contenant la séquence consensuelle de frontière de portée (::) sont admis. On évitera cependant d'utiliser des noms se terminant par cette séquence bien que le moteur ne soit pas tenu de vérifier cette condition.

Exemples :

<%xml source="../foo.xml" scope="XMLDATA" ...
<%xml source="../foo.xml" scope="XML::FOO" ...

Les variables générées par translation DIML commenceront par les préfixes respectifs "XMLDATA::" et "XML::FOO::". Le "scoping" de variables est surtout intéressant lorsque plusieurs fichiers partageant la même DTD sont ouverts dans la même structure DIML. On notera que le moteur ajoute la séquence de séparation de portée.

5.4 L'attribut select

L'attribut select est certainement le plus délicat à décrire. Il agit comme un sélecteur (similaire à XSL) sur l'arbre XML de données source, pour extraire des éléments et les transformer en variables DIML. La sélection peut porter sur un élément unique, un ensemble d'éléments partageant un même niveau de hiérarchie, un élément de DTD particulier ou répondant à des valeurs d'attributs spécifiques.

5.4.1 Forme générale du sélecteur

La sélection d'éléments dans le document XML suppose la résolution d'un chemin d'accès dans l'arbre XML. Pour cela, un certain nombre de nœuds doivent être considérés, permettant par résolution du niveau d'arbre, de réduire ce dernier aux élements sélectionnés.

La forme générale d'une expression de sélection est une suite d'identifiants d'éléments séparés par des points, évoquant une portion d'un chemin d'accès depuis la racine (élément racine XML) jusqu'aux éléments terminaux. La forme générale de la sélection est donnée par la définition BNF (Bakkus-Naur Form) étendue suivante :

XML_tree_identifier ::= [ *[ node_id "." ] XML_tree_identifier ] | node_id
node_id             ::= element_id ?[ "(" selector ")" ] | '*'
element_id          ::= #NMTOKEN | '*'
selector            ::= [ *selector_expr "," selector ] | selector_expr
selector_expr       ::= var_name [ pattern_operator pattern | comparison_operator operand ]
var_name            ::= "@" attribute_id
comparison_operator ::= "==" | "<" | ">" | "<=" | ">=" | "!="
operand             ::= #CDATA | [ quotemark #CDATA quotemark ]
quotemark           ::= "'"
pattern_operator    ::= "=~" |"!~"
pattern             ::= #EREGEXP

Note :#EREGEXP est une expression régulière POSIX 2 étendue

Le sélecteur d'un nœud d'élément est un attribut ayant une valeur discriminante. La réaction d'une implémentation à un sélecteur dont les valeurs ne permettent pas un pointage univoque d'un élément n'est pas spécifiée. Cette spécification suppose que les valeurs des discriminants choisis permettent une identification unique de l'élément discriminé.

On notera pour la suite de l'exposé quelques définitions terminologiques utiles :

nœud de sélection
Portion de l'expression de sélection agissant sur un nœud de l'arbre XML.
Elément discriminé
Elément XML associé explicitement à un sélecteur.
Elément totalement discriminé
Elément dont le nœud de sélection a une solution unique.
Elément sélectionné
Elément répondant au nœud de sélection, quant sa solution est multiple.
Discriminant
Attribut sélectionné pour filtrer les éléments sources. Un appel XML peut faire figurer plusieurs discriminants dans le même sélecteur.
Identifiant
Nom d'un élément XML.
Selecteur de nœud
Expression de sélection agissant au niveau d'un nœud de sélection donné.
Elément ignoré
Elément ni sélectionné, ni discriminé.
5.4.2 Discrimination totale d'un élément

Un élément est totalement discriminé lorsque l'ensemble des conditions ci-après sont réalisées :

  • Le premier nœud est le nœud racine, un fils unique de la racine, ou un élément totalement discriminé de la racine.
  • Tous les nœuds d'instance multiples ont au moins un sélecteur défini
  • Toutes les expressions de selection ont un résultat unique
  • Le dernier identifiant est un identifiant d'attribut ou les identifiants réservés innerText innerXml ou innerHtml
5.4.3 Sélection de références d'éléments XML

Il y a "sélection de référence xml" lorsque la chaîne de sélection s'arrête sur le nom d'un nœud, sans préciser de nom d'attribut, ni utiliser les trois pseudo-attributs innerText, innerHtml, et innerXml. Cette forme de sélection obtient le sous arbre XML formé en dessous de l'élément discriminé. Il équivaut à l'application à l'élément d'un attribut virtuel innerXml.

Par exemple, en reprenant le fichier source donné plus haut :

<%xml
   source = "foo.xml"
   select = "root.box(@@=='0')"
   %>

ce sélecteur extrait la variable :

%root[0].box[0].innerXml%

dont la valeur est :

      <box>
         du contenu de box.box
         <element attrib1="value1" attrib2="value2">sample a</element>
         <element attrib2="value2" attrib1="value2">sample b</element>
      </box>
   
5.4.4 Sélection d'attributs d'éléments XML

On doit considérer que les attributs des éléments XML sont aussi source d'information. Il est donc possible d'étendre l'identifiant unique jusqu'au valeurs d'attributs d'un nœud. Tout attribut déclaré est donc accessible par un sélecteur de la forme :

XML_attribute_identifier ::= XML_tree_identifier ] "." attribute_id | reserved_attribute
reserved_attribute ::= "innerText" | "innerXml" | "innerHtml"

On se reportera ci-avant pour la définition de XML_tree_identifier.

Les attributs implicites innerText, innerXml et innerHtml sont particuliers.

5.4.5 L'attribut virtuel innerText

Lorsque la source est assimilable à un document textuel, le XML sert essentiellement à qualifier les informations qui le composent. Tout élément XML de ce document constitue une portion du document qui peut avoir sa propre unité sémantique. Par exemple, si l'on considère le fragment XML suivant :

 
<root>
   <adresse>
      <numero>20</numero>
      <voie>Av du Parc</voie>
      <codeposte><I><B>95011</B></I></codeposte>
      <ville>CERGY</ville>
      <pays>FRANCE</pays>
   </adresse>
   <message>Le contenu d'un message</message>
</root>

Il peut être souhaîtable de récupérer la totalité de l'adresse comme un seul fragment texte. C'est le rôle de l'attribut innerText qui détruit tout balisage inférieur au niveau d'élément auquel il est appliqué dans le sélecteur. Par exemple, le sélecteur :

 
adresse.innerText

construit une variable unique contenant la séquence :

      20
      Av du Parc
      95011
      CERGY
      FRANCE

On remarque ici que les fins de ligne sont respectés à l'intérieur de l'élément "adresse", de façon à ce que les données textualisées restent identifiables. Globalement, et pour simplifier l'analyse, ce sont tous les caractères d'espacement qui sont conservés par le filtre de textualisation.

5.4.6 L'attribut virtuel innerXml

L'attribut virtuel innerXml permet également d'obtenir une certaine interprétation de l'élément XML sélectionné par le filtre. Ce méta-attribut représente l'ensemble du contenu de l'élément XML sans aucun filtrage.

En reprenant l'exemple précédent, le sélecteur :

 
adresse.innerXml

donne le résultat:

      <numero>20</numero>
      <voie>Av du Parc</voie>
      <codeposte><I><B>95011<B></I></codeposte>
      <ville>CERGY</ville>
      <pays>FRANCE</pays>
5.4.7 L'attribut virtuel innerHtml

L'attribut virtuel innerHtml est la dernière forme de représentation du contenu qui admet de conserver d'éventuelles balises HTML lors de l'interprétation de l'élément. En reprenant l'exemple précédant,

 
adresse.innerHtml

construit une variable unique contenant la séquence

 
      20<BR>
      Av du Parc<BR>
      <I><B>95011</B></I><BR>
      CERGY<BR>
      FRANCE<BR>

Par défaut, les séquences de fin de ligne contenues dans la séquence obtenue par l'extraction seront remplacées par la fin de ligne HTML (<BR>). Le commutateur nobr de l'instruction <%xml inhibe cette dernière transformation.

5.4.8 L'utilisation d'un motif comme filtre d'élément

Il devra être possible de sélectionner des familles d'éléments en indiquant une forme plus large de l'élément. L'implémentation des métas '*', '^', '$', '?' est recommandée. Celle du '.' (POSIX) est déconseillée pour des raisons évidentes d'interprétation. Les significations des métas recherchées sont :

  • * : un nombre quelconque de caractères
  • ? : un caractère quelconque
  • ^ : cale le motif au début du nom d'élément
  • $ : cale le motif en fin du nom d'élément
5.4.9 L'utilisation du super-méta **

La présence du super-méta ** en fin de sélecteur demande l'extraction de toutes les dépendances du noeud de sélecteur précédent. L'extracteur génèrera toutes les variables d'attributs et de contenus de l'élément ainsi que de tous ses sous-élements, quelque soit la profondeur hiérarchique.

Attention : Ce méta peut provoquer la génération d'un nombre important de variables et augmenter notablement le temps d'extraction.

5.5 L'attribut alias

L'attribut alias permet de réduire l'identifiant DIML translaté à une forme canonique. L'objectif de cette canonisation est de rendre plus concises les variables d'arrivées et de mieux les intégrer dans le flux DIML.

La valeur de cet attribut est un préfixe servant à générer le nom de variable. Dans tous les cas, les variables générées sont des tableaux DIML dont le nom est construit sur la base du préfixe d'aliasing, auquel est concaténé le dernier nom d'attribut (réel ou virtuel).

5.6 L'attribut nobr

L'attribut nobr inhibe la transformation des fins de ligne en éléments <BR> lors de la production de méta-valeurs innerHtml.

6 Exemples

Soit un fichier XML source :

<?xml version="xml1.0" ?>
<root>
   <box1 id="1">
      <box2>
         du contenu de box2
         <element attrib1="value1" attrib2="value2">sample a</element>
         <element attrib2="value3" attrib1="value2">sample b</element>
      </box2>
   </box1>
   <box1 id="2">
      <box2>
         <element attrib1="value1">sample2</element>
      </box2>
   </box1>
</root>

6.1 Sélections à résolution unique

6.1.1 Elément complètement discriminé


<%xml source="fich.xml" 
select="box1(@id='1').box2.element(@attrib1='value2')" 
alias="ELM1" %>

<element attrib1="value1" attrib2="value2">sample a</element>

On note dans cette expression l'affectation de cette valeur à la variable DIML %ELM1%.

6.1.2 Contenu complètement discriminé


<%xml source="fich.xml" 
scope="SAMP1" select="box1(@id='1').box2.element(@attrib1='value2').innerText" 
alias="ELM" %>

sample a

On note dans cette expression l'affectation de cette valeur à la variable DIML %SAMP1::ELM%.

6.1.3 Attribut d'élément discriminé


<%xml source="fich.xml" 
scope="SAMP3" select="box1(@id='1').box2.element(@attrib1='value2').attrib2" 
alias="ATTR" %>

value 3

On note dans cette expression l'affectation de cette valeur à la variable DIML %SAMP3::ATTR%. On s'apperçoit par ailleur que l'unicité de la discrimination sur l'attribut "attrib2" n'est due qu'à la sélection par l'attribut "attrib1".

6.2 Sélections à résultat multiple

6.2.1 Elément sans discriminant


<%xml source="fich.xml" 
select="box1.box2.element(@attrib1='value1')" 
alias="ELM1" %>

ELM1§1§1§value1 : sample a ELM1§2§1§value1 : sample2

Le manque de discrimination du selecteur vient de l'incapacité de sélectionner de quel élément "box1" il s'agit. Cette indétermination n'est pas levée au niveau de la sélection d'élément, car le selecteur de nœud utilisé laisse passer deux instances d'élément, une dans la première "box1", l'autre dans la deuxième.

6.2.2 Attribut sur un élément non discriminé


<%xml source="fich.xml" 
select="box1(@id='1'.box2.element.attrib1" 
alias="ATTR2" %>

ATTR2§1§1§1 : sample a ATTR2§1§1§2 : sample2

Dans ce cas, la première indiscrimination est donnée par l'appel de l'élément "element" sans discriminant. L'appel de l'attribut "attrib1" ne lève pas la discrimination.


All material is copyleft V.G. FREMAUX (EISTI France) 1999 to 2003 except explicitly mentioned