Nous présentons dans ce chapitre les techniques de transformation nécessitant une spécification additionnelle aux structures et aux instances de documents. Ces techniques regroupent les filtres qui utilisent une spécification implicite de la transformation et les systèmes de transformation explicites qui interprètent un ensemble de directives servant à paramétrer les transformations. Ces deux familles de transformations sont regroupées dans ce chapitre car il existe des similarités entre les techniques utilisées, comme on le verra plus loin.
La première section présente un exemple de transformation simple qui nous permet d'illustrer les techniques de transformation étudiées. Nous abordons ensuite les filtres de conversion, puis nous détaillons les systèmes de transformation explicite existant avant de présenter les transformations utilisées par Amaya.
Pour illustrer les différentes techniques de conversion, nous utiliserons un exemple de transformation de document structuré. Cet exemple nous sert dans ce chapitre à montrer la syntaxe utilisée. Il nous sert également à mettre en valeur les limites et les points forts de certains systèmes de transformation.
Nous avons choisi un exemple à la fois simple et représentatif de l'ensemble des transformations de documents structurés. Il met en oeuvre les opérations de transformation décrites dans le chapitre précédent (structuration, déplacement d'éléments, suppression et insertion de niveaux de structure, changement de type).
Cet exemple reprend la DTD mail présentée au chapitre précédent (et rappelée dans la figure 12) qui décrit la structure générique d'un message électronique. Un document mail (figure 13) comprend les éléments recipient, sender, subject et textbody correspondant respectivement aux destinataire, expéditeur, sujet et contenu du message. Le contenu est composé d'une suite de paragraphes eux-mêmes composés de texte et de citations identifiées par l'élément cite. L'élément mail porte l'attribut ref défini dans la DTD qui peut être utilisé par les applications pour référencer le message.
<!ELEMENT mail (date, recipient, sender, subject, textbody) > <!ELEMENT date (#PCDATA) > <!ELEMENT recipient (#PCDATA) > <!ELEMENT sender (#PCDATA) > <!ELEMENT subject (#PCDATA) > <!ELEMENT textbody (p)+ > <!ELEMENT p (#PCDATA | cite)* > <!ELEMENT cite (#PCDATA) > <!ATTLIST mail ref CDATA #REQUIRED >
Figure 12 - La DTD XML des documents mail
<mail ref="sb332"> <date>30-07-1998</date> <recipient>Cecile.Roisin@inrialpes.fr</recipient> <sender>Stephane.Bonhomme@inrialpes.fr</sender> <subject>littérature XML</subject> <textbody> <p>Bonjour Cécile,</p> <p>As-tu lu <cite>SGML, Java and the Future of the Web</cite></p> <p>Stéphane.</p> </textbody> </mail>
Figure 13 - Un document mail
Notre exemple consiste à transformer le document mail de la figure 13 en un document message dont la structure générique est décrite par la DTD de la figure 14. Les deux DTD diffèrent sur les 6 points suivants :
Tous les systèmes de transformation ne permettent pas de traiter
tous les aspects de la transformation de mail
en
message
. Nous donnerons, lors de la présentation des
systèmes de transformation, l'ensemble de leur possibilités en
référence à cette liste. Nous pourrons ainsi
différencier les systèmes par leur capacité à
réaliser les différents aspects de cette transformation.
<!ELEMENT message (référence, expéditeur, destinataire, contenu) > <!ELEMENT référence (#PCDATA) > <!ELEMENT expéditeur (#PCDATA) > <!ELEMENT destinataire (#PCDATA) > <!ELEMENT contenu (titre, corps) > <!ELEMENT titre (#PCDATA) > <!ELEMENT corps (para)+ > <!ELEMENT para (#PCDATA) > <!ATTLIST message date CDATA #REQUIRED >
Figure 14 - La DTD XML des documents message
Le document que l'on désire obtenir à l'issue de la transformation est donné dans la figure 15.
<message date="30-07-1998"> <référence>sb332</référence> <expéditeur>Stephane.Bonhomme@inrialpes.fr</expéditeur> <destinataire>Cecile.Roisin@inrialpes.fr</destinataire> <contenu> <titre>littérature XML</titre> <corps> <para>Bonjour Cécile,</para> <para>As-tu lu «SGML, Java and the Future of the Web»</para> <para>Stéphane.</para> </corps> </contenu> </message>
Figure 15 - Document message
Un filtre est une application permettant de convertir un document d'un format donné dans un autre. Il existe des filtres permettant la transformation de documents entre toutes sortes de modes de représentation (traitement de texte, PostScript, PDF, LaTeX ou documents structurés). On peut citer les filtres de traduction de LaTeX vers HTML, de document formatés vers des documents SGML, conformes à des DTD particulières comme les DTD d'acquisition (TEI).
La caractéristique qui distingue les filtres de conversion des autres systèmes de transformation est la définition figée des transformations qu'ils permettent d'effectuer. Ces transformations sont définies lors du développement du filtre qui ne peut pas être paramétré pour effectuer des transformations différentes. Par exemple, un filtre permettant de traduire les documents mail en message comme montré dans notre exemple ne pourra effectuer que cette transformation et elle se fera toujours en suivant les mêmes règles.
Les filtres sont conçus pour répondre aux besoins spécifiques de certaines applications :
Il convient de noter que de nombreuses applications documentaires utilisent des filtres de conversion pour traduire en HTML les document qu'elles produisent. Il est également prévisible qu'à l'avenir ces applications utiliseront le format XML pour le stockage. Ceci relativise l'intérêt de cet aspect de la transformation de documents et nous pousse à nous concentrer sur la transformation de documents structurés.
L'implémentation de filtres de conversion est très dépendante des formats des documents source. Si le format source est linéaire (contenu textuel et directives de formatage, comme c'est le cas pour les documents produits par les traitements de texte), le filtre parcourt le document, interprétant les directives de formatage pour produire leur équivalent dans le format cible.
[Here is a Drawing]Figure 16 - Principe du filtre de conversion
Si le modèle des documents source est structuré (SGML, XML), le filtre intègre généralement un analyseur syntaxique (parser) permettant d'associer des actions - en l'occurrence la génération du document cible - aux débuts et fins d'éléments de la structure.
Certains des systèmes de transformation explicite présentés dans la section suivante permettent de programmer des filtres de conversion de documents de façon interactive (Chameleon [Mamrak 89]) ou en utilisant une spécification déclarative de la transformation (IDM [Digithome], XSL [Clark 98], DSSSL [ISO 94]).
Pour notre part, nous avons expérimenté la technique de conversion de documents par filtres lors de la création d'un nouveau schéma, nommé rapport, pour la classe de documents article définie dans l'éditeur Thot. Ce nouveau schéma se différencie du précédent principalement sur deux points :
D'autres différences mineures concernent les noms des types d'éléments et l'introduction de niveaux de structure supplémentaires dans la structure générique définie par le schéma rapport.
Notre filtre est programmé en utilisant l'API de Thot [Quint] qui fourni des primitives d'accès aux éléments du document source et des primitives de construction pour créer le document cible. La fonction de transformation crée l'équivalent d'un élément du document source passé en paramètre, cette fonction est ensuite appelée récursivement sur chacun des fils de l'élément source. L'arborescence ainsi obtenue est ensuite insérée dans la structure du document cible. De plus, la fonction de transformation effectue un traitement particulier sur les éléments appartenant à certains types (bibliographie, références) au lieu de traiter récursivement leur descendance.
Cette application nous a permis de nous familiariser avec la transformation de documents, mais nous a également montré que, bien qu'utilisée couramment par les membres du projet Opéra pour la transformation d'Articles en Rapports, une telle application n'a pas pu être ré-utilisée pour d'autres situations de transformation.
Les filtres de conversion ont pour atout leur efficacité car ils appliquent des algorithmes de transformation adaptés aux formats traités. Aucune information autre que le contenu du document ne doit être analysée ce qui accroît les performances de ces outils. Les filtres sont adaptés au traitement de collections importantes de documents suivant une méthode déterminée à l'avance et ne nécessitant donc pas d'interaction. Dans certains cas spécifiques, les filtres peuvent être utilisés dans les systèmes d'édition interactive, notamment lors de commandes d'édition précises portant sur des types d'élément déterminés.
La contrepartie de cette non-interactivité est que l'utilisateur ne peut pas guider le cours de la transformation. De plus, les filtres ne sont pas adaptables, c'est à dire que leur conception est dépendante des formats qu'ils manipulent, ils ne peuvent pas servir non plus à transformer les documents entre deux DTD quelconques.
Dans notre problématique, les filtres de conversion présentent un intérêt pour convertir des documents depuis des formats divers vers un format structuré sur lequel nous pouvons ensuite appliquer les techniques de transformation exposées plus loin.
Un système de transformation explicite s'appuie sur une information additionnelle aux documents et à leurs modèles, exprimant la façon dont un document doit être transformé. Cette information permet de paramétrer les transformations et par conséquent de les adapter aux besoins.
Les systèmes de transformation explicite prennent comme données un document source (ou une partie de document) et un ensemble de spécifications de transformation. Les spécifications de transformation sont interprétées puis utilisées pour convertir l'instance source en une instance cible (figure 17).
[Here is a Drawing]Figure 17 - Architecture générale d'un système de transformation explicite
Ainsi, deux aspects sont considérés dans l'étude de ces systèmes : le langage de spécification des transformations et la mise en oeuvre de la conversion à partir de ces spécifications dans le moteur de transformation. Il faut noter que le langage dans lequel sont exprimées les transformations et le moteur qui les réalise sont dépendants l'un de l'autre.
Nous proposons dans la section 3.3.1 une classification des méthodes de transformation explicite. Les classes de langages utilisés par ces méthodes sont présentés dans la section 3.3.2. La section 3.3.3 est une revue des principaux systèmes utilisant la technique explicite. Un bilan des outils de transformation explicite est donné dans la section 3.3.4.
La section 3.4 est une étude particulière d'un travail réalisé dans le cadre de cette thèse, qui visait à évaluer la technique de transformation explicite dans un contexte d'édition interactive de documents structurés. Cette expérience à débouché sur la réalisation d'un système de transformations explicites pour l'éditeur Amaya.
Les moteurs de transformation se différencient selon deux critères principaux :
Dans cette approche, une transformation est conduite par un parcours dans l'ordre préfixe de la structure du document source. Un ensemble de règles ou de primitives de génération du document cible est associé à un événement du parcours (début de document, début d'élément, fin d'élément, présence d'attribut, valeur d'attribut, etc.).
Dans certains formats de documents tels que MIF ou pdf, les éléments se sont pas ordonnés dans la forme stockée. Les documents apprtenant à de tels formats sont chargés par le système de transformation qui rétablit l'ordre dans lequel les éléments seront traité par la transformation.
La figure 18 illustre la génération des événements lors de la transformation d'un document de la classe message. L'événement de début d'élément message est généré, puis la descendance de cet élément est parcourue pour produire les événements qui y sont associés, l'événement fin d'élément message est produit lorsque toute sa descendance à été parcourue.
[Here is a Drawing]Figure 18 - Production des événements lors de la transformation dirigée par la source.
Les transformations dirigées par la source permettent une sélection des événements en fonction du contexte dans lequel intervient l'élément de structure auquel est attaché cet événement. Ce contexte couvre les éléments qui ont été traités précédemment par le système au moment où il applique une règle : les ancêtres de l'élément courant, ses voisins de gauche et leurs descendants.
La transformation dirigée par la source permet une génération linéaire du document cible. Dans ce cas, les transformations ont la propriété de préserver l'ordre des éléments. La génération peut également être arborescente si le système de transformation fournit des fonctions de construction de structure comme la création, l'insertion ou la copie d'éléments.
L'approche des transformations dirigées par la source est proche du mécanisme d'un analyseur syntaxique et la plupart des outils proposant cette approche sont fondés sur des analyseurs de documents structurés (CoST 2 [English 96a], STIL [Schrod 95]). Ces systèmes bénéficient des fonctionalités de l'analyseur pour la production des événements et fournissent un mécanisme de génération de la structure cible.
Les transformations par requêtes permettent de construire le document cible par extraction d'éléments du document source. Une transformation est décrite par un ensemble de règles « requête-actions ». Une requête permet de sélectionner un sous-ensemble des éléments du document source sur lesquels doit être appliquée une (ou plusieurs) action(s) de transformation.
Le processus de transformation par requêtes se fait en deux phases :
Des formes de requêtes différentes interviennent lors de ces deux phases : les requêtes utilisées par la première permettent la reconnaissance d'une structure particulière de l'instance source. Ces requêtes se comportent comme des filtres sur la structure du document. La seconde phase utilise des requêtes pour extraire l'information du document source pour l'intégrer dans le document cible.
Selon les systèmes de transformation, une importance différente est donnée à ces deux phases. Certains systèmes (IDM, Balise) ne proposent que la phase d'application des règles de génération, celle-ci se faisant de façon séquentielle et inconditionnelle. Si la génération se fait de manière linéaire, les déclarations sont ordonnées dans l'ordre de la structure du document produit. Une telle transformation peut être exprimée à l'aide du langage de script du système IDM présenté dans la section 3.3.3.1.
Si le système utilise les requêtes pour faire une sélection des règles à appliquer, l'ensemble des requêtes est évalué et les règles associées à celles retournant un résultat sont appliquées. L'ordre d'application de ces règles peut varier d'un système à l'autre. Cet ordre peut être :
Les transformations explicites sont exprimées soit dans un langage spécifique soit dans un langage de programmation classique.
Les langages de transformation peuvent être de nature déclarative ou impérative :
Certains systèmes utilisant une expression déclarative proposent une interface graphique pour spécifier les transformations. C'est le cas par exemple de Chameleon qui permet d'associer de manière interactive les types d'éléments d'une structure générique source avec ceux d'une structure cible.
Cette section décrit plusieurs systèmes de transformation explicite couvrant l'ensemble des méthodes et utilisant les formes de langages exposées précédemment. Nous illustrerons les langages associés à ces systèmes en donnant l'expression de la transformation des documents mail en documents message décrite au début de ce chapitre.
Nous présentons d'abord les systèmes de transformation utilisant des langages ayant une plus forte composante impérative. Puis nous décrirons des systèmes intégrant une approche plus déclarative.
Le tableau de la figure 19 recense les systèmes présentés dans la suite et les caractéristiques des méthodes de transformation qu'ils utilisent.
Système | méthode de transformationordre d'application des règles | génération des éléments cibles | Langage | ||||
---|---|---|---|---|---|---|---|
IDM | source ou requêtes | mixte | impératif | ||||
Balise | source ou requêtes | mixte | impératif | ||||
Cost / STIL | source ou requêtes | linéaire | impératif | ||||
DSSSL | requêtes | arborescente | fonctionnel | ||||
XSL | requêtes | arborescente | déclaratif + impératif |
||||
Chameleon | source | linéaire | déclaratif | ||||
SgmlQL | requêtes | arborescente | déclaratif | ||||
Scrimshaw | requêtes | linéaire | déclaratif |
Figure 19 - Caractéristiques des systèmes de transformation explicites
IDM (Intelligent Document Manager [Digithome]), développé par la société Digithome, est un environnement de manipulation de documents électroniques orienté vers la transformation de documents structurés. Cet environnement fournit une interface de programmation (API) permettant de programmer facilement des filtres de conversion de documents structurés vers des formats divers (HTML, LaTeX, Microsoft Windows Help).
L'API IDM permet de localiser des éléments de structure en utilisant des requêtes sur les ancêtres et les descendants d'un noeud, sur les voisins, sur la présence et la valeur des attributs, ou encore sur le contenu des éléments textuels. L'API permet d'implémenter des transformations procédurales et dirigées par la destination. Les primitives de l'API sont fournies par un ensemble de classes C++, dont la classe DI qui fournit les méthodes de sélection de noeud ou la classe IDM qui contient les méthodes de lecture du document source et d'écriture sur le flot de sortie.
L'exemple suivant montre la transformation du document mail en message et illustre ainsi la méthode de transformation par requêtes avec une génération linéaire des éléments cibles.
Les requêtes utilisent les méthodes de la classe
DI
préfixées par Move
pour
déplacer le noeud courant dans la structure. La méthode MoveB
permet de déplacer la sélection courante vers son premier fils,
MoveT permet de la déplacer sur le parent, MoveR et MoveL permet de la
déplacer vers l'élément suivant ou
précédent. La partie génération utilise les
méthodes DI->GetData
pour accéder au contenu des
éléments et IDM->Progress
pour écrire sur
le flot de sortie le résultat de la transformation.
DI->MoveTT(); // accès à l'élément racine DI->MoveB(); // accès à l'élément date IDM->Progress ("<message date=\"%s\">", DI->GetData()); DI->MoveT(); // accès à l'élément mail IDM->Progress ("<référence>%s</référence>\n", DI->GetAttrValue ("ref")); DI->MoveB(); //accès à l'élément sender DI->MoveR(); DI->MoveR(); IDM->Progress ("<expéditeur>%s</expéditeur>\n", DI->GetData()); DI->MoveL(); //accès à l'élément recipient IDM->Progress ("<destinataire>%s</destinataire>\n", DI->GetData()); IDM->Progress ("<contenu>\n"); DI->MoveR(); DI->MoveR(); // accès à l'élément subject IDM->Progress ("<titre>%s</titre>\n", DI->GetData()); DI->MoveR(); // accès à l'élément textbody IDM->Progress ("<corps>\n"); DI->MoveB(); do if (DI->IsGI("cite") == IDTRUE) IDM->Progress ("« %s »", DI->GetData); else IDM->Progress ("%s", DI->GetData); while (DI->MoveNext == IDTRUE)
Dans cet exemple nous supposons que la structure du document source est correcte et que tous les éléments de cette structure sont présents. Un traitement supplémentaire serait nécessaire pour vérifier l'existence de chacun de ces éléments.
IDM propose de plus un langage de script qui permet de spécifier des transformations dirigées par la source. La déclaration de la transformation est alors plus concise, mais ne permet pas de réaliser tous les aspects de la transformation de l'exemple : la spécification suivante ne remplit que les critères 1, 2 et 3 énoncés dans la section 3.1 :
START_mail Progress ("<message>") END_mail Progress ("</message>") START_recipient Progress ("<destinataire>") END_recipient Progress ("</destinataire>") START_sender Progress ("<expéditeur>") END_sender Progress ("</expéditeur>") START_subject Progress ("<contenu> <titre>") END_subject Progress ("</titre>") START_textbody Progress ("<corps>") END_textbody Progress ("</corps> </contenu>") START_cite Progress ("«") END_cite Progress ("»") !DATA Progress ("$DATA")
Avec ce langage de script déclaratif, la génération de ce document est également linéaire. Par conséquent, la transformation dirigée par la source, spécifiée par le langage de script ne permet pas de modifier l'ordre des éléments (critères 4, 5 et 6).
Grâce à sa nature procédurale, IDM permet des transformations complexes de documents structurés entre DTD ainsi que vers de nombreux formats de documents. Néanmoins l'utilisation de cet outil requiert une bonne pratique de la programmation et de l'algorithmique pour mettre en oeuvre ces transformations. Le langage de script est très simple, mais ne permet d'effectuer que des transformations simples : la génération de l'instance cible est linéaire, et les traitements sont associés à un type d'élément indépendamment du contexte dans lequel ils apparaissent.
Balise [AIS 96] est un environnement de développement d'applications documentaires basées sur les standards SGML et XML. Cet environnement comprend un langage de programmation. Il est développé par la société AIS Berger-Levrault. Le langage Balise permet de manipuler la représentation arborescente des documents à travers des fonctions d'accès et de modification de la structure. Ces fonctions permettent soit de modifier la structure d'un document existant, comme montré ci-dessous, soit de générer un nouveau document en insérant les éléments créés dans une nouvelle arborescence comme le montre le deuxième exemple. Les instructions de contrôle du langage Balise sont les mêmes que celles d'un langage de programmation impératif classique (Pascal, C).
Ce langage fournit également des primitives de création et de copie d'éléments. Ces fonctions permettent de programmer un grand nombre de transformations. Une fonction transformant des documents mail en message s'écrit :
function Mail2Message (doc) { var elem = root (doc); // accès à l'élément racine changeGI (elem, "message"); // change le type du noeud // mail var reg = attr ("ref", elem); // accès à l'attribut ref var newelem = Move (soc, "référence", ref); insertSubTree (elem, 1, newelem); //cree l'élément ref elem = firstChild (elem); // accès à l'élément date addAttr (root(doc), date, content (elem)); elem = rightSibling (elem); // accès à l'élément recipient changeGI (elem, "destinataire"); elem = rightSibling (elem); // accès à l'élément sender changeGI (elem, "expéditeur"); CutSubTree (elem); // déplace l'élément // expéditeur insertSubTree (root(doc), 1, elem); elem = rightSibling (elem); // accès à l'élément title changeGI (elem, "titre"); var body = rightSibling (elem); //accès à l'élément textbody cutSubtree (elem); // déconnecte le noeud titre insertSubtree (body, 0, elem); // insère titre avant le // 1er fils de body changeGI (body, "contenu"); // change body en contenu elem = Node (doc, "corps"); // crée le noeud corps insertSubtree (body, 1, elem); // insère corps après le // 1er fils de contenu var elpar = rightSibling (body); while (elpar != nothing) { // parcourt les éléments p cutSubtree (elpar); // déplace chaque p dans insertSubtree (elpar, -1, body) // l'élément corps changeGI (elpar, Para); for elem in searchElemNodes (elpar, "cite") { // génère les guillemets changeContent (elem, format ("«%s»", content(elem))); flattenSubTree (elem); // retire les éléments cite } } }
L'algorithme utilisé dans cet exemple parcourt le document source en
appliquant des traitements spécifiques aux éléments
rencontrés. Ces traitements permettent d'implémenter les six
aspects énoncés dans l'exemple. La nature impérative du
langage Balise impose une description complète de la transformation. En
particulier, pour ignorer les éléments cite, il faut
explicitement les retirer (fonction flattenSubTree
) ou rechercher
leur contenu d'une manière spécifique.
Balise permet également de spécifier des transformations dirigées par la source. Pour cela, Balise permet d'associer des traitements aux événements de l'analyseur XML intégré. Des traitements sont associés aux événements de début et de fin pour les éléments, des clauses contextuelles peuvent être ajoutées à cette définition (par exemple : début des éléments de type p se trouvant à l'intérieur d'un élément textbody). Pour limiter l'occupation de la mémoire lors de la transformation, le contexte est restreint aux ancêtres et aux voisins précédents de l'élément concerné par l'événement. Nous donnons ci-dessous un extrait d'une transformation dirigée par la source exprimée dans le langage Balise. Cette spécification utilise le style déclaratif pour associer des traitements aux événements de l'analyseur, ces traitements utilisant un langage procédural pour générer l'arborescence du document cible.
//initialisation main { eventLookAhead(true); } // transformation de l'élément mail element mail { on start { changeGI ("message"); var root = Elem ("mail"); } } // transformation de l'élément date en attribut element date { on start { var ladate = content (currentNode()); AddAttr (root, "date", ladate); } } // transformation de l'élément recipient element recipient { on start { changeGI ("destinataire"); // insère expéditeur comme premier fils de body cutTree (currentNode()); insertSubTree (root, 0, currentNode()); } } // transformation de l'élément sender element sender { on start { changeGI ("expéditeur"); // insère expéditeur comme premier fils de body cutTree (currentNode()); insertSubTree (root, 0, currentNode()); } } // transformation de l'élément subject element suject { on start { changeGI ("titre"); // crée l'élément contenu // et l'insère comme dernier fils de body var elcontenu = Node ("contenu"); insertSubTree (root, -1, elcontenu); // insere titre dans contenu insertSubTree (elcontenu, 0, currentNode()); // crée l'élément corps // et l'insère comme dernier fils de contenu var elcorps = Node ("corps"); insertSubTree (elcontenu, -1, elcorps); } } // transformation des éléments para element p { on end { changeGI ("para"); cutTree (currentNode()); insertSubTree (elcontenu, -1, currentNode()); } // élimination des éléments cite, génération des guillemets element cite { on begin { changeContent (currentNode(), format ("«%s»", content(currentNode()))); flattenSubTree(); } }
Balise, avec l'approche dirigée par la source, se différencie du langage de script d'IDM par le fait que la génération ne se fait plus de manière linéaire, mais par la construction d'une structure arborescente du document. Cette approche fournit une souplesse accrue dans la façon de placer les éléments cibles. De plus elle n'impose pas la génération des balises de début et de fin d'élément. En contrepartie, elle ne permet de produire que des documents structurés au format SGML ou XML. De plus, ce mode de génération nécessite la représentation en mémoire de l'arbre du document cible qui peut être importante.
La combinaison de la transformation dirigée par la source avec la
modification de la structure du document source peut produire des effets de
bord négatifs : le traitement d'un événement peut
entraîner des modifications dans la structure du document et conduire
à l'omission de sous-arbres entiers lors de la transformation. C'est
pour éviter ces effets de bord que Balise permet de dupliquer
préalablement la structure du document source (avec la fonction
DumpSubTree
) pour obtenir une instance servant à la
génération du document, l'autre étant modifiée par
les traitements de ces événements.
En conclusion, comme pour IDM, la composante impérative du langage Balise nécessite une connaissance de la programmation. Par contre, son approche déclarative permet la spécification de transformations plus complexes que celles d'IDM grâce à la possibilité de sélectionner des ancêtres lors de l'association d'une règle à un type d'élément et à la génération arborescente.
CoST 2 [English 96a] (Copenhagen SGML Tool) est un outil qui permet de spécifier des transformations de documents structurés en Tcl. Cet outil est un logiciel libre développé par la société ART (Advanced Rotorcraft Technology, Inc.) Ce langage intègre de puissantes fonctions de traitement de la composante textuelle des documents telles que la reconnaissance d'expressions régulières et leur remplacement. Cet outil de transformation est associé au parser sgmls [Clark].
CoST 2 propose une méthode de transformation par requêtes. Celles-ci servent à sélectionner les éléments du document source qui doivent être transformés mais également à identifier ceux qui sont utilisés lors de la génération.
Les requêtes de sélection des éléments source
sont définies par les mots clés foreachNode
et
withNode
associés à un traitement Tcl. Le
traitement est appliqué au premier élément ou à
l'ensemble des éléments respectant la requête. Lors de
l'application du traitement, l'élément ayant satisfait la
requête est appelé élément courant.
Les traitements sont des scripts Tcl et permettent d'écrire de façon linéaire le document cible sur un flot de sortie. Ces traitements peuvent utiliser des requêtes sur le document source pour en extraire le contenu. Ces requêtes permettent d'accéder aux éléments environnant l'élément courant (ancêtres, voisins et descendants), aux attributs des éléments et au contenu des feuilles.
La transformation de mail en message à l'aide de CoST 2 s'exprime de la façon suivante :
puts "<message date=\"" withNode withgi date {puts "[query content]"} puts "\">" puts "<reference>" withNode withgi message hasatt ref { puts "[query attval ref]" } puts "</référence><expéditeur>" withNode withgi sender {puts "[query content]"} puts "</expéditeur><destinataire>" withNode withgi sender {puts "[query content]"} puts "</destinataire><contenu><titre>" withNode withgi title {puts "[query content]"} puts "</titre><corps>" foreachNode withgi p { puts "<para>" puts "[query content]" puts "</para> } puts "</corps></contenu></message>"
Les requêtes d'extraction du contenu sont introduites par le
mot-clé query
, tandis que les requêtes de
sélection sont illustrées ici par le mot-clé
foreachNode
. La transformation présentée ci-dessus
ne permet pas de traduire les element cite de la structure source,
car la composition des requêtes n'est pas suffisamment expressive et
l'opérateur foreachNode
ne permet pas de
différencier le traitement à associer au début, au
contenu et à la fin de chaque élément. Pour pallier ce
manque d'expressivité, CoST 2 permet d'ordonnancer les traitements
selon la structure du document source en les associant aux
événements de l'analyseur. Les actions TCL utilisant les
requêtes sont alors associées aux événements de
début et de fin d'élément.
Cet outil, profitant de la modularité apportée par le langage de script Tcl permet le développement de modules, ce qui conduit à une expression simple mais limitée des transformations. Parmi ces modules, on peut citer Simple Cost, qui permet une spécification simple de transformations dirigées par la source avec une génération linéaire par écriture sur le flot de sortie, RatFink [English 96b] qui permet la spécification de transformations de documents structurés SGML en documents au format RTF.
STIL [Schrod 95] et SGMLSpm [1] sont des outils de transformation qui utilisent des principes similaires à ceux de CoST. STIL est développé à l'université de Darmstadt, il utilise le langage Lisp pour la description des requêtes. SGMLSpm développé par David Megginson de l'université d'Ottawa est un module perl permettant l'expression de requêtes et de règles de transformation similaires à celles de CoST2.
Exrep [Lambolez 95] est un outil de réécriture permettant de traiter un flot de texte en entrée et d'y appliquer un ensemble de règles de réécriture. Exrep est particulièrement adapté aux domaine de l'extrction et de la réutilisation de contenu de document.
Chaque règle de réécriture est formée d'une expression régulière permettant la reconnaissance d'une sous-chaîne dans la chaîne d'entrée, et d'une chaîne de remplacement se substituant à la sous-chaîne reconnue par l'expression régulière.
Les apport de Exrep sur les outils de réecritures standards d'Unix, tels que lex [Levine 92] et awk [Dougherty 92] sont :
A cause de sa généricité lui permettant de traiter tout type de format de document, Exrep ne propose pas de primitive permettant de gérer facilement les balises SGML ou XML. La spécification d'une transformation doit donc contenir les expressions régulières permettant de rcoonaitre la syntaxe des balises de marquage.
Les transformations proposées par le système Exrep peuvent être considérées comme des transformations par requêtes avec génération linéaire. Ces transformations permettent le remplacement des balises (la substitution de <mail> par <message>, le remplacement de l'élément <date> par un attribut ou bien de l'attribut ref par un élément). Les transformations permettent l'insertion de balises en fonction du contenu d'un élément (remplacement des guillemets par l'élément cite). La principale limitiation d'Exrep est de ne pas permettre le déplacement d'éléments dans la structure, des systèmes tels que Scrimshaw (3.3.3.9) permettent de manipuler des variables permettant la mémorisation d'éléments pour leur réutilisation au cours de la transformation, ce qui permet les déplacement et leur réplication.
Chameleon [Mamrak 89] est un outil interactif de définition de structures génériques et de transformation entre formats de documents. Chaméleon, aussi appelé ICA pour Integrated Chameleon Architecture a été développé à l'université de l'Ohio en coopération avec la compagnie HaL Computer Systems, Inc.
SGML est utilisé par Chameleon comme format de description générique des documents et sert de pivot entre les documents de différents formats (figure 20).
[Here is a Drawing]Figure 20 - Utilisation de SGML comme format pivot pour la transformation entre formats de documents
L'information de formatage des documents originaux est d'abord convertie sous forme de balises SGML. Les documents ainsi marqués sont transformés vers une structure générique SGML, enfin, ces documents sont exportés vers le format de destination voulu.
Ces transformations successives sont spécifiées par plusieurs modules de Chameleon (cf. figure 21) :
Figure 21 - Étapes de la transformation d'un document LaTeX en
Troff
avec ICA
Chaque module permet la génération de filtres, représentés par des cercles sur la figure 21, qui permettent le passage du document d'un état dans un autre (source, marqué, SGML, cible).
L'originalité de ce système est l'utilisation de SGML comme format central pour la conversion de documents. Cela permet de s'appuyer sur des DTD existantes pour la représentation commune des formats source et cible. Pour utiliser cette méthode de transformation, deux étapes sont nécessaires : la structuration permet de représenter le document d'origine sous une forme structurée, l'export permet de traduire le document structuré dans le format de destination.
Les modules de spécification de transformations s'appuient sur les outils d'analyse syntaxique Lex et Yacc. Les modules Retag, Intag et Gen2spec ne permettent que de spécifier des réécritures de l'information de formatage ou de structure associée aux documents. Le module Spec2gen est le plus intéressant du point de vue de la transformation car c'est lui qui permet les opérations de manipulation de structure des documents.
Le module Spec2gen permet l'association des balises du document source avec les types définis dans la DTD SGML. Cette association est décrite à l'aide d'expressions régulières permettant d'exprimer l'organisation des balises sources. Certaines balises peuvent être perdues lors de cette étape car la structure générique SGML ne permet généralement pas de représenter toutes les informations nécessaires à la présentation du document. Dans l'exemple ci-dessus, le document est découpé en paragraphes, mais les sauts de ligne sont perdus.
Les expressions régulières permettent d'associer des règles de transformation (en l'occurrence un type d'élément SGML) à une séquence de balises dans le document marqué. Ces séquences d'éléments sont exprimées en termes de listes, d'alternatives et peuvent contenir des éléments optionnels. Les expressions régulières ne permettent pas d'exprimer la hiérarchie des balises source ; elles sont donc adaptées pour spécifier la transformation d'un ensemble de balises sans relations hiérarchiques, mais il est nécessaire d'étendre leur syntaxe et leur sémantique pour les utiliser dans un contexte de documents structurés (voir section 3.4.2.1).
DSSSL [ISO 94] est une norme de l'ISO pour définir la sémantique ou le style des documents SGML. DSSSL comprend deux parties : STTP (SGML Tree Transformation Process) et SSP (Semantic Specific Process), c'est la partie STTP qui assure les transformations de structure. Le but de la transformation de structure proposée par DSSSL est l'adaptation des documents SGML aux différents support de présentation.
Les spécifications de transformations sont exprimées dans le langage scheme et décrivent l'association entre les types de la DTD d'origine et ceux de la DTD destination. Ces spécifications d'associations sont composées de trois parties :
La norme DSSSL, bien que datant de 1994, n'a connu qu'une implémentation partielle : Jade [Clark], associée à l'analyseur sgmls. La proposition XSL présentée dans la suite joue un rôle similaire à celui de DSSSL pour les documents XML.
XSL [Clark 98] est une proposition du consortium W3C pour la définition de feuilles de styles (stylesheets) pour les documents XML. Le langage XSL comprend deux parties :
Le langage XML utilise le mécanisme des NameSpaces [Bray 98b] qui est également une proposition du consortium W3C. Les namespaces permettent de définir des espaces de noms dans les documents : les noms de types d'éléments sont précédés d'un préfixe indiquant à quel espace de nom ils appartiennent. XSL utilise l'espace de nom xsl pour identifier les directives de transformation des éléments de structure crées par la transformation.
Une feuille de style est composé d'un ensemble d'expressions (nommés templates) décrivant chacune une transformation élémentaire. Chaque template est représenté par un élément XML du type xsl:template.
Le modèle de transformation de XSL repose sur des requêtes spécifiant la structure des éléments source. Une requête permet de sélectionner un élément en fonction de son contexte ascendant (parents, ancêtres), la présence et la valeur des attributs des éléments constituant ce contexte.
Les requêtes XSL sont contenues par l'attribut match des éléments template.
Le contenu d'un élément template est constitué de l'ensemble des éléments qui sont créés dans le document cible par la transformation et de directives XSL qui permettent un traitement lors de la transformation. Ces directives permettent :
des règles conditionnelle en fonction d'une requête.
Lorsqu'une feuille de style XSL est appliquée, le template dont la requête identifie l'élément racine de la structure source est d'abord appliqué. ce template peut explicitement provoquer l'application des autres templates à d'autre éléments de la structure source.
La feuille de style suivante permet de transformer un document mail en message :
<xsl:stylesheet> <!-- transformation de l'élémnt mail --> <xsl:template match="mail"> <message date="{date}"> <reference> <xsl:value-of expr="attribute(ref)"/> </reference> <!-- traite les fils de mail dans l'ordre où ils apparaissent dans la structure message --> <xsl:process select="sender"/> <xsl:process select="recipient"/> <xsl:process select="textbody"/> </message> </xsl:template> <!-- transformation de l'élément sender --> <xsl:template match="sender"> <expéditeur> <xsl:process-children/> </expéditeur> </xsl:template> <!-- transformation de l'élément recipient --> <xsl:template match="recipient"> <destinataire> <xsl:process-children/> </destinataire> </xsl:template> <!-- transformation de l'élément subject --> <xsl:template match="subject"> <titre> <xsl:process-children/> </titre> </xsl:template> <!-- transformation de l'élément textboby --> <xsl:template match="textbody"> <contenu> <!-- transformation de l'élément subject --> <xsl:process select="ancestor(mail)/subject"/> <corps> <xsl:process-children/> </corps> </contenu> </xsl:template> <!-- traite l'élément p --> <xsl:template match="p"> <para> <xsl:process-children/> </para> </xsl:template> <!--transformation de l'élément cite --> <xsl:template match="cite"> « <xsl:process-children/> » </xsl:template> </xsl:stylesheet>
XSL permet de traiter tous les aspects de la transformation de mail en message présentée dans la section 3.1. Ce langage, encore en cours de définition, est parmi ceux présentés ici celui permet d'exprimer les transformations les plus complexes. Pour cela, il intègre la méthode transformation par requêtes, une construction descriptive de la structure cible et des instructions de contrôle permettant de guider la transformation.
La norme XSL étant destinée à la transformation de document pour produire une structure proche de son image physique il a été conçu pour la transformation des documents dans leur intégralité. Cependant, les déclarations XSL sont modulaires : une transformation est décrite par un ensemble de templates qui portent chacun sur un sous-ensemble du document source. Les templates peuvent donc être utilisés pour une transformation locale et faire partie de la spécification d'une transformation plus générale.
La contrepartie de cette déclaration modulaire est la nécessité de spécifier la façon de transformer chaque élément du document source.
SgmlQL [Le Maitre 95], [Le Maitre 98] est un système de transformation fondé sur un langage reprenant les principes du langage d'interrogation de bases de données SQL. Ce système est développé au Laboratoire Parole et Langages (LPL) à l'université de Toulon. Ce système permet la construction de documents à partir de l'information contenue dans une base de documents SGML.
Chaque script SgmlQL décrit la construction d'un document SGML en
utilisant des opérateurs de construction de document,
d'élément et d'attribut. Le langage permet d'évaluer des
requêtes construites avec les opérateurs SQL (Empty, Count,
Sum, Indexing, Concatenation, Shrink, Exists, Forall, Select... from... where,
Transpose... from... where
) mais appliquées à des
documents SGML au lieu de bases de données relationnelles.
SgmlQL permet par exemple d'extraire l'information contenue dans un ensemble de messages dont la structure est décrite dans notre exemple. Supposons que le fichier messages.sgml contienne un ensemble de messages. On affecte son contenu à une variable globale par l'expression :
global $mess = file "messages.sgml"
Les requêtes utilisent cette variable globale pour en interroger le contenu :
count (every message within $mess)
(every message within $mess)[1:10]
forall $m in (every destinataire within $mess): text($m) match "Cécile"
select every message within $m from $m in $mess where text (first destinataire within $m) match "Cécile"
Le résultat des requêtes peut être appliqué aux opérateurs de construction d'éléments pour que le script produise un document SGML. Le script permettant de convertir le document mail en message s'écrit :
document docdtd: "message.dtd" body: element MESSAGE attr:{DATE = text(first DATE within $mess)} content: [ element REFERENCE content:[(first MAIL within $mess)->REF], element EXPEDITEUR content:[content(first SENDER within $mess)], element DESTINATAIRE content:[content(first RECIPIENT within $mess)], element CONTENU content:[ element TITRE content:[content(first TITLE within $mess)], element CORPS content:[replace every P as $p within $mess by element PARA content: content ( replace every CITE as $c within $p by "« ".text($c)." »") ] ] ]
La transformation de mail en message n'est pas la plus adaptée pour montrer les possibilités du langage SgmlQL, qui est conçu pour la construction de documents à partir d'une collection de documents SGML. Ce système répond à un besoin de transformation assez différent de celui concerné par notre problématique : l'utilisation et la génération de documents structurés à partir d'information provenant de sources diverses (bases de données, serveurs d'information, moteurs de recherche, World Wide Web, etc.).
Néanmoins l'exemple ci-dessus montre que les expressions SgmlQL sont compactes. De plus ce système permet de mettre en oeuvre tous les aspects de la transformation donnés en 3.1.
En contrepartie, le temps d'évaluation des requêtes qui est un facteur déterminant pour l'utilisation d'une telle approche dans un éditeur interactif est important pour les requêtes du type SQL. L'approche de la transformation proposée par ce système est plus adaptée au traitement automatique de bases de données documentaires qu'à la transformation d'instances au coup par coup, telle qu'elle est utilisée dans les éditeurs interactifs.
Scrimshaw [Arnon 93] est un langage de pattern-matching entre arbres permettant de spécifier des transformations de documents structurés. Ce langage se fonde sur une approche requêtes/action et une génération linéaire du document cible.
Scrimshaw permet de manipuler des variables pouvant contenir des listes de sous-arbres de la structure des documents. Ces variables sont affectées par le résultat de requêtes sur la structure du document. Les requêtes utilisent des opérateurs de pattern-matching classiques appliqués au document source :
Dans la partie PATTERN associée à un opérateur grep, il est possible d'assigner des sous-parties à des variables. Ces variables peuvent être utilisées dans la partie EXPRESSION de la règle.
Scrimshaw fournit également un mécanisme de pipeline permettant d'appliquer plusieurs transformations successives à une même instance.
La transformation de mail en message dans le langage Scrimshaw s'exprime de la façon suivante :
{mail [ date [<vdate:#>] recipient [<vrec:#>] sender [<vsend:#>] title [<vtitle:#>] textbody [ <vlp:map[{p[<vp:#*>]->para[<vp>]}] ||mapSearch{cite [vcite:#*] -> "«",<vcite>,"»"}] > ] ] -> message [ expediteur [<vsend>] destinataire [<vrec>] contenu [ titre [<vtitle>] corps [<vlp>] ] ] }
La partie requête de cette transformation assigne respectivement les
variables vrec
, vsent
et vtitle
au
contenu des éléments recipient, sender et
title du document d'origine. La requête traitant les
paragraphes est plus complexe : un opérateur map
change
d'abord les éléments p en para puis au
résultat de cette transformation est appliqué un
opérateur mapSearch
permettant de remplacer les
éléments cite par des guillemets. Le résultat de
la transformation de la suite de paragraphes constituant le corps du
mail est assigné à la variable vlp
.
Scrimshaw est limité à la transformation des éléments et ne permet pas de spécifier des transformations impliquant les attributs. Cette limitation ne permet pas de prendre en compte les éléments date et reference dans la transformation de mail en message.
La partie génération de la transformation est une déclaration de la structure du document cible en utilisant les variables initialisées dans la partie requête.
Au delà de la syntaxe utilisée, le principe de transformation
proposé par Scrimshaw se différencie de celui de DSSSL par la
façon de générer le document cible. Au lieu d'utiliser
les expressions de priorité pour définir l'ordre des
transformations, Scrimshaw permet d'intégrer les opérateurs de
pattern-matching à l'intérieur des requêtes. Ainsi les
transformations peuvent être faites « à la volée
» lors du pattern-matching (opérateurs map
et
mapsearch
dans l'exemple). Le mécanisme de pipeline permet
également de contrôler l'ordre dans lequel sont effectuées
les transformations.
La diversité des systèmes de transformation explicite vient du fait qu'ils répondent à des besoins applicatifs différents. Nous identifions ici les relations entre les méthodes de transformation et le contexte applicatif (voir section 2.4) dans lequel elles sont utilisées :
Ces systèmes peuvent également proposer des facilités pour spécifier des transformations dirigées par la source en reproduisant le comportement d'un parser (langage de script d'IDM, mécanisme d'événements de Balise). Cette possibilité permet de réécrire la structure et le contenu du document, pour l'exportation vers un autre format de documents par exemple, mais ne permet pas de transformations complexes entraînant une modification de l'ordre des éléments ou leur déplacement dans les niveaux de structure. En contrepartie, les transformations sont plus faciles à spécifier et ne réclament pas l'expertise nécessaire au développement de systèmes de transformation plus complexes.
Ces transformations utilisent des algorithmes plus coûteux en temps de calcul. Les requêtes pouvant être appliquées à la globalité du document, la structure de celui-ci doit être parcourue à chaque évaluation. La place mémoire nécessaire à ces processus est également importante car elle doit contenir la structure dans son intégralité. C'est une des raisons pour lesquelles les transformations par requêtes ne sont pas utilisées dans des systèmes interactifs, mais trouvent leur application dans la conversion de grandes quantités de documents, mettant en oeuvre des processus de conversion non interactifs.
L'expression des transformations par requêtes n'est pas aussi simple que celle des transformations dirigées par la source car les correspondances entre les éléments source et les éléments produits par la transformation ne sont pas directes. Par conséquent la programmation de ces transformations nécessite une connaissance plus approfondie des structures génériques des documents et de l'interprétation des requêtes par le système.
Cette partie expose une réflexion sur la possibilité d'expérimenter un système de transformations explicites dans le cadre applicatif de l'édition de document. Nous présentons ici les choix que nous avons fait préalablement à cette expérience.
Pour l'édition de documents structurés, les transformations explicites doivent remplir des conditions de performances et de localité adaptées à cette application. Le système doit pouvoir prendre en entrée un ensemble de transformations et se baser sur différents critères pour n'en retenir qu'une. Ces critères sont :
La structure résultant d'une transformation peut ne pas être conforme à la structure générique définissant la classe de documents. Le système doit contrôler que la transformation ne produise que des structures conformes.
Figure 22 - deux transformations de liste en table
Les systèmes de transformation dirigés par la source permettent une application rapide des transformations en n'utilisant qu'une place mémoire minimale. De plus ils permettent une expression simple des transformations. Cependant ces systèmes, généralement associés à une génération linéaire du document cible, sont trop limités pour des transformations impliquant un déplacement des éléments dans la structure du document.
Les requêtes de sélection permettent une sélection des transformations en fonction de la structure de l'instance source. Ce type de requête permet au système de proposer à l'utilisateur un choix de transformations pré-sélectionnées.
L'utilisation de requêtes de sélection permet de spécifier la génération des éléments cibles par construction (SgmlQL, XSL). Cette spécification permet de mêler des éléments fixes et des éléments identifiés dans le document source par les requêtes.
Cette approche permet une expression plus lisible de la structure produite par la transformation mais est limitée lorsque cette structure est dépendante de la structure de l'instance source. Par exemple la spécification de la transformation d'une liste ne doit pas présupposer de connaître le nombre d'éléments contenus dans la liste. Dans ce cas il est nécessaire d'étendre la syntaxe des règles de génération avec des opérateurs de contrôle permettant de spécifier qu'une structure doit être crée autant de fois qu'il y a d'éléments dans la structure source. La déclaration de la production du document perd alors son aspect déclaratif et intègre une composante procédurale plus difficile à appréhender.
La complexité induite par cette approche est la raison pour laquelle nous avons cherché à combiner le mode de génération dirigé par la source et par construction des éléments cibles. La partie action des expressions de transformation que nous proposons est composé d'un ensemble de règles de génération décrivant chacune la construction d'une branche dans la structure des éléments engendrés. Ces règles sont relatives à des éléments identifiés dans la requête et déclenchées lors d'un parcours dans l'ordre préfixe des éléments reconnus par cette même requête.
Ainsi, nous avons expérimenté la technique de transformation explicite dans un environnement d'édition de documents HTML. Nous avons étendu le mécanisme et nous avons adapté l'interface pour prendre en compte l'édition de nouvelles structures telles que HTML 4.0 et MathML (Mathematical Markup Language). Ce système de transformation est présenté dans la section suivante.
L'éditeur de documents HTML Amaya [Quint 94] est développé à l'INRIA par une équipe du consortium W3C. Nous avons implémenté dans cet éditeur une fonction de transformation d'éléments HTML et XML [Bonhomme 96]. Cette expérience nous a permis d'évaluer les techniques de transformation explicite, de sélection de structures par requêtes et d'application des règles dirigées par la source. L'intégration de ce système dans un éditeur interactif lui confère quelques spécificités que n'ont pas les systèmes de transformation présentés précédemment.
Il est nécessaire que les transformations intervenant lors de l'édition du document soient performantes : le délai d'attente ne doit pas excéder la seconde. C'est pourquoi nous n'utilisons que des méthodes rapides de transformation (expressions régulières, application des règles dirigées par la source).
Amaya utilise une représentation structurée des documents édités. La structure des documents édités reste continuellement en conformité avec la DTD HTML (contrôle de structure strict). Par conséquent, les structures produites par le système de transformation doivent également produire des éléments conformes à la DTD.
Les transformations effectuées lors de l'édition ne portent généralement pas sur l'ensemble du document mais sur un nombre limité d'éléments choisis par l'utilisateur.
L'interface utilisateur doit être simple et rendre dans la mesure du possible les transformations transparentes. Pour cela, nous nous appuyons sur la sélection effectuée par l'utilisateur et les menus et boutons d'édition proposant à l'utilisateur les types d'éléments définis par la DTD. Les transformations sont spécifiées à l'avance, dans un fichier. L'utilisateur n'a pas besoin de connaître ce fichier et n'a pas à spécifier les transformation au moment où il veut les effectuer.
Nous avons voulu proposer un système de transformation explicite demandant une expression minimale des transformations. Plus précisément, nous voulons permettre de n'exprimer que les transformations des éléments de structure qui subissent des modifications, le système devant se charger de copier des éléments dont la structure est inchangée.
Deux interfaces utilisateur sont proposées pour les transformations dans Amaya impliquant deux modes d'interaction avec le système de transformation. L'utilisateur peut demander explicitement la transformation de la sélection courante par l'entrée de menu Transformer. Il peut également déclencher une transformation en sélectionnant un passage du document et en sélectionnant un type d'élément dans une palette.
Dans le premier cas, l'ensemble des transformations pouvant s'appliquer à la sélection est proposé à l'utilisateur dans un menu construit dynamiquement, lui permettant ainsi de sélectionner la transformation voulue. Nous appellerons par la suite ce mode d'interaction appel explicite.
Dans le second cas, la première transformation (dans l'ordre de leur déclaration) produisant le type d'élément demandé et applicable à la sélection courante est déclenchée. L'utilisateur n'a pas forcément conscience qu'il provoque une transformation de structure et n'interagit qu'une fois avec le système. C'est, par exemple, ce qui se produit lorsqu'une table est sélectionnée et que l'on clique sur l'icône Liste de la barre de boutons d'Amaya. La table sélectionnée est alors transformée en en listes imbriquées. Ce mode d'interaction est nommé appel induit.
Un fichier portant l'extension .trans
contient la description
de l'ensemble des transformations prédéfinies relatives à
une DTD. Chaque transformation comprend trois composantes :
Une spécification de transformations a donc la syntaxe suivante :
Transformations := Transformation + Transformation := Nom ':' Requete '{' Règles '}' Nom := TEXTE
Les requêtes sont des expressions comprenant les opérateurs choix (|), séquence (,), liste (+), élément optionnel (?) et contenu ([ ]) utilisés pour combiner des noeuds. Chaque noeud permet d'identifier un ensemble d'éléments de la structure du document lorsque celle-ci est confrontée aux requêtes.
Requête := Exp_requete Exp_requete := Noeud | '(' Exp_choix ')' |
'(' Exp_seq ')' | Exp_liste | Exp_option Exp_choix := Exp_requete ( '|' Exp_requete ) + Exp_seq := Exp_requete ( ',' Exp_requete ) + Exp_liste := Exp_requete Op_liste Op_liste := '+' Exp_option := '?' Exp_requete
Ces expressions décrivent une organisation de noeuds qui est utilisée comme filtre sur la structure des éléments source. Les noeuds déclarés dans les requêtes peuvent être des noeuds simples ; les éléments qu'ils permettent d'identifier sont alors reconnus quelque soit leur contenu. Une expression peut aussi spécifier des noeuds avec un contenu, appelés noeuds composés ; les éléments qu'ils permettent d'identifier sont alors reconnus si et seulement si leur contenu est reconnu.
Un noeud simple est défini par un nom de type d'élément. L'ensemble des éléments identifiés par un noeud peut être restreint par la spécification d'une présence ou d'une valeur d'attribut. Les noeuds de la requête peuvent également être nommés pour faire le lien avec les règles de génération. Plusieurs noeuds peuvent porter le même nom pour leur appliquer la même règle de génération :
Noeud := Noeud_simple | Noeud_composé Noeud_composé := Noeud_simple '[' Exp_requete ']' Noeud_simple := [Nom ':'] Type_elem | [Nom ':'] '<' Type_elem ( ' ' Attr_spec )* '>' Nom := TEXTE Type_elem := TEXTE Attr_spec := Nom_attr | Nom_attr '=' Val_attr Nom_attr := TEXTE Val_attr := '"' TEXTE '"'
Le type de l'élément peut être soit un nom de type tel qu'il est défini dans la DTD, soit un jocker (*) qui représente n'importe quel type d'élément. Si une spécification d'attribut n'est pas associée à une valeur, seule la présence de cet attribut est requise pour que l'élément soit reconnu. La valeur associée à un attribut permet de filtrer les éléments qui ont un attribut du type spécifié qui a cette valeur.
Les quelques exemples suivants illustrent la syntaxe des requêtes utilisées par Amaya. La première requête identifie une liste non vide d'éléments de type li. La seconde identifie un élément div contenant un élément h2 suivi d'une liste éventuellement vide d'éléments p ou autres.
li + div [h2, ?(p | *)*]
L'exemple suivant permet de différentier les éléments
de type h2 selon qu'ils sont dans des divisions de premier niveau
(T1
) ou de second niveau (T2
).
div [T1:h2, *+, div [T2:h2, *+]+ ]
La requête suivante identifie les éléments de type p
portant un attribut id de valeur quelconque et un attribut
classe ayant la valeur commentaire
parmi une liste
d'éléments quelconques.
( <p id classe="commentaire"> | * )+
Les requêtes du système de transformation d'Amaya servent d'une part à la sélection des extraits de documents sur lesquels les transformations peuvent être appliquées, d'autre part à l'identification d'éléments du document pour l'application de règles de transformation. Ces requêtes sont proches de celles proposées par XSL.Une première différence avec ce dernier est qu'Amaya permet d'associer des règles à plusieurs noeuds de la requête tandis que XSL ne permet que l'utilisation d'un seul élément identifié par la requête dans une règle de construction. Une seconde différence est que les requêtes d'Amaya permettent de spécifier un contexte plus étendu dans lequel il est possible de désigner les voisins des éléments ; dans les requêtes XSL seuls les ascendants des éléments source peuvent être précisés.
Amaya ne s'appuie pas sur le mécanisme de requêtes pour la génération mais sur un parcours dirigé par la structure avec une génération arborescente des éléments résultant de la transformation. C'est pourquoi la syntaxe des requêtes et la sémantique associée est différente des systèmes Scrimshaw et SgmlQL qui utilisent les requêtes comme mode de construction du document cible.
La syntaxe que nous avons présentée est inspirée de celle des expressions régulières et plus compacte que celle de XSL qui est exprimée en XML. Cette caractéristique permet une analyse plus rapide des fichiers de transformation. La vitesse de l'interprétation est un facteur important car il est possible de modifier le fichier contenant les expressions de transformation au cours d'une session d'édition et de profiter immédiatement de ces modifications. Le fichier est alors interprété à la volée lorsqu'une transformation est déclenchée.
Les règles de génération des éléments cibles sont composées d'un identifiant et de la spécification d'une branche à générer dans l'arbre de structure du document. Ces deux composantes sont séparées par le caractère '>'.
Règles := Règle+ Règle := Identifiant '>' Branche ';' Identifiant := TEXTE
L'identifiant fait la relation entre la règle de transformation et un ensemble de noeuds de la requête. Il peut être un nom défini dans la partie requête et la règle sera alors appliquée à l'ensemble des éléments reconnus par les noeuds de la requête portant ce nom. Il est ainsi possible d'associer la même règle à un ensemble d'éléments de types différents. Par exemple, la transformation d'une table HTML en liste s'écrit :
Liste : table [tbody [tr [(Cell:td|Cell:th)]+ ] ] { tr > :ol.li; Cell > ol:li; }
Il est également possible, grâce au renommage des noeuds de la
requête, d'associer des règles différentes à des
noeuds différents, mais représentant le même type
d'élément. Par exemple, la transformation suivante transforme
une liste simple HTML en liste titrée ; le premier item de la liste
simple (Premier:li
) étant transformé en titre de
liste.
Liste titrée : ul [Premier:li, (Autres:li)+] { Premier > dl:dt; Autres > dl.dd; }
La spécification de la branche engendrée par une règle est relative à la structure engendrée par les règles précédemment appliquées. Lorsque la première règle est appliquée, la branche complète est crée. Le règles suivantes peuvent soit engendrer une nouvelle branche complète, soit engendrer une branche qui est attaché à l'un des éléments créés par la règle précédente, grâce aux éléments de placement définis ci-dessous. L'élément de plus haut niveau de la dernière branche entièrement crée est appelée élément racine de la structure produite.
Les éléments crées par l'application d'une règle sont toujours insérés après (comme frère suivant) les éléments crées par les règles précédemment appliquées. La descendance est écrite sous la forme d'une liste dont les éléments sont séparés par les caractères '.' et ':', le caractère ':' ne pouvant apparaître qu'une seule fois par règle. Ce caractère permet de séparer la branche en deux ensembles d'éléments :
Branche := [ Placement ] ':' [ Génération ] | [ Génération ] Placement := Élément ( '.' Élément )* Génération := Élément ( '.' Élement )* [ Fin_génération ] | '/' Fin_génération := [ '.' '$' | '.' '"' TEXTE '"' ] ['#'] Élément := Élément_simple | Élément_attr Élément_simple := Nom
L'un et l'autre de ces ensembles étant optionnels, de nombreuses combinaisons sont possibles. Nous exposons tous les cas ci-dessous en les illustrant d'un schéma de la structure engendrée par la règle. Les arbres de gauche représentent la structure engendrée avant l'application de la règle, l'arbre de droite, cette même structure après l'application de la règle. Les noeuds de placement sont représentés en vert et les noeuds de génération sont présentés en rouge. Lorsqu'ils ont une influence, nous avons représenté, dans l'arbre de gauche, les noeuds de placement et de génération de la règle précédente.
|
|
Si tous les éléments de placement ne sont pas présent dans la branche la plus à droite de la structure crée préalablement à l'application de la règle, ceux-ci sont également crées.
|
|
elem
dans la
requête, et identifié par data dans le schéma)
est copié à la position déterminée par les
éléments de placement.
|
|
|
|
|
|
|
|
|
|
La distinction entre éléments de placement et éléments de construction permet de définir de façon précise où les éléments doivent être créés ou copiés dans la structure du document. Cette approche est intermédiaire entre la génération linéaire et la génération arborescente : l'ordre des éléments dans la structure est conservé, mais ils peuvent être insérés à des niveaux de structure spécifiques. Ce choix permet de proposer une syntaxe simple pour les expressions de transformation (une liste d'éléments) tout en répondant aux besoins de transformations au cours de l'édition. Ces transformations sont localisées et interviennent sur un petit nombre d'éléments, elles ne font pas de réordonnancement d'éléments qui peuvent être perturbants pour l'utilisateur.
Contrairement aux systèmes utilisant une génération linéaire des documents cibles, il n'est pas nécessaire de spécifier l'intégralité des structures produites par la transformation, Amaya s'appuie sur le modèle générique des documents et applique une politique visant à conserver l'intégralité du contenu des éléments transformés. En conséquence, les règles de transformation ne spécifient que les niveaux de structure du document où interviennent les changements. Par exemple, les règles de la transformation exposée ci-dessus et permettant de transformer les listes en listes titrées ne spécifient que la transformation des éléments listes (ul) et item (li) en éléments liste titrées (dl), titres de listes (dt) et corps de listes titrées (dd). Le contenu des listes est implicitement transféré de la liste source dans la liste titrée, à la condition que la structure générique l'autorise.
Des symboles spéciaux peuvent être utilisés dans une règle de génération. Ces symboles permettent un autre comportement que le comportement par défaut de la génération de l'instance cible.
La transformation suivante permet par exemple de transformer une séquence d'élément en liste HTML :
Liste : (item:*)+ { item > ul:li.$; }
La transformation suivante permet de transformer une table en liste, en ignorant le titre de la table (caption) :
Liste : table [caption, tbody[tr[td+]+]] { caption > /; td > ul:li; }
A2Img : <a href> { a > <a href=a.href>.<img src="link.gif">; a > a:strong #; }
Ce symbole peut être utilisé dans plusieurs règles pour dupliquer la descendance des éléments source lors de la transformation.
Le symbole '$' peut également être utilisé lorsque plusieurs règles relatives à un même noeud sont déclarées, son rôle est alors également d'identifier la règle sur laquelle doit être transféré l'élément source et son contenu. Par exemple, la transformation suivante permet de transformer une séquence d'éléments quelconques en liste HTML et de précéder chacun d'entre eux d'une titre :
Promo : (Item:*)+ { Item > ul:li.h2."Promotion : " ; Item > ul.li:$ ; }
Le système de transformation d'Amaya permet également de générer des attributs sur les éléments spécifiés dans les règles de génération. Ces attributs peuvent prendre des valeurs fixes ou copier des valeurs d'attributs présents dans la structure source.
Élément_attr := '<' Nom ( ' ' Attribute)* '>' Attribute := Nom '=' Value Value := Nom '.' Nom | '"' TEXTE '"'
La transformation suivante transforme une suite de paragraphes, dont certains portent des attributs style et d'autres contiennent des éléments b, en une suite de paragraphes ne portant que des attributs style et des éléments span portant un attribut style.
BtoCSS : ( p [(*|b)+])+; { p > <p style=p.style>:; b > p:<span style="font-face:bold;">; }
La règle p
spécifie que chaque paragraphe de la
structure source est transformé en un paragraphe portant un attribut
style qui prend la valeur de l'attribut style du paragraphe
original. La règle b
transforme chaque
élément b en un élément span et
crée un attribut style attaché à cet
élément. Avec la manipulation des attributs, les transformations
proposées par Amaya permettent de créer une présentation
spécialisée des éléments en utilisant le
mécanisme des CSS2 (Cascading Style Sheets, level 2) [Bos 98] proposé par le W3C pour la
présentation des documents HTML.
Il est possible de générer des feuilles de texte au cours de la transformation : le dernier noeud de la partie génération d'une règle peut être une chaîne textuelle (première règle de la transformation Promo). Si une règle qui provque la création d'éléments textuels est la seule attachée à un élément de la requête, sa descendance est alors remplacée par la feuille de texte spécifiée.
Nous montrons, à l'aide d'un exemple, le déroulement d'une transformation explicite dans Amaya. Nous décrivons d'abord comment sont représentées les requêtes, puis comment cette représentation est utilisée pour leur interprétation, ensuite nous expliquons comment se déroule la génération de la structure cible.
Prenons comme exemple la transformation
dans un document HTML d'une suite de titres de deux niveaux
(h1
et h2
) entrecoupés
d'éléments quelconques (*) en une structure de liste
titrées imbriquées s'écrit :
Listes Titrées:(h1,(C1:*)+,(h2,(C2:*)+)*)+; { h1 > dl:dt; C1 > dl.dd:*; h2 > dl.dd.dl:dt ; C2 > dl.dd.dl.dd:*; }
L'ensemble des requêtes de toutes les expressions de transformation déclarées est représenté sous la forme d'un automate qui est éclaté en fonction de la profondeur des requêtes. Ainsi, l'interprétation de l'expression de transformation donnée en exemple produit l'automate de reconnaissance de structure présenté figures 23. La génération de cet automate ne se fait que lors de la première transformation d'une session d'édition. L'automate est alors gardé en mémoire et utilisé lors des transformations suivantes.
L'automate construit est éclaté de façon à
obtenir un automate pour chaque niveau de structure de l'ensemble dans les
requêtes interprétées. Chacun de ces automates de niveau
permettant de déterminer quelles parties de requêtes
reconnaissent une séquence d'éléments voisins,
appelée sous-requête (partie
Exp_requête
de la règle
Noeud_composé
de la grammaire de la section 3.4.2.1).
Les transitions d'un automate de reconnaissance sont étiquetées par le nom du type correspondant à la transition et un ensemble de couples d'identificateurs : le premier identifie de façon unique la sous-requête à laquelle appartient le noeud représenté par la transition, il est appelé ide. Si la descendance de ce noeud est spécifiée par la requête, le second identificateur, appelé idinf, identifie la sous-requête définissant cette descendance dans l'automate du niveau inférieur, il est nul sinon.
L'automate présenté dans la figure 23, ne représente qu'une sous-requête et aucune transition ne fait référence à une sous-requête car aucune descendance de noeud n'est définie dans la requête. Par conséquent le couple d'identificateurs associé à chaque transition est : (ide = 1, idinf = 0).
[Here is a Drawing]Figure 23 - Automate de reconnaissance de la requête (h1,(C1:*)+,(h2,(C2:*)+)*)+
La figure 24 montre les automates des deux
niveaux de structure construits lors de l'interprétation d'une seconde
requête : h1, (ol[li+]|ul[li+]
) qui reconnaît un
titre suivi d'une liste numérotée (ol
) ou non
(ul
). L'interprétation de cette requête étend
l'automate de niveau 0 de la figure 23 et
produit un automate de niveau 1 pour reconnaître les sous-requêtes
(li+
). Les transitions associées aux noeuds parents des
sous-requêtes référencent les transitions correspondantes
dans la sous-requête par le deuxième paramètre de leur
couple d'identificateurs (ul (2 1)
et ol (2 2)
).
Notons que deux couples d'identificateurs sont associés à la
transition représentant le noeud h1 dans l'automate de niveau 0 car
cette transition est utilisée pour la reconnaissance des deux
requêtes.
Figure 24 - Automates de reconnaissance des deux requêtes
L'algorithme de reconnaissance parcourt l'arbre de structure de l'instance source depuis le niveau le plus bas jusqu'aux éléments constituant la sélection. Chaque ensemble d'éléments frères (qui ont le même parent) est analysé par l'automate du niveau correspondant. Si cet ensemble est reconnu en utilisant des transitions portant toutes un ou plusieurs identificateurs ide, ces identificateurs sont remontés au niveau supérieur et seules les transitions ayant un identificateur idinf appartenant à cet ensemble permettent la reconnaissance du niveau supérieur.
Un ensemble d'éléments frères est reconnu par un automate si et seulement si il existe une suite de transitions qui a les propriétés suivantes :
Le résultat de la reconnaissance sur un niveau est l'ensemble des ide répondant à la troisième propriété.
Une table de nommage des éléments est construite durant la reconnaissance pour associer aux éléments de la source les règles relatives aux noeuds de la requête. L'algorithme ne détaille pas la reconnaissance d'attributs qui est une extension de l'égalité entre le type de l'élément et le type exprimé dans la requête.
Le résultat de l'évaluation de requêtes est ensemble de transformation dont les requêtes ont été reconnues par l'instance source. Dans le cas d'un appel explicite, cet ensemble est présenté à l'utilisateur pour lui permettre de sélectionner une transformation de son choix, Dans le cas d'un appel induit, la transformation correspondant à la première requête de l'ensemble est appliquée.
L'application des règles de transformation se fait lors d'un parcours de l'arbre de structure de la source. L'instance source est préalablement déconnectée du corps du document pour pouvoir générer les éléments définis dans les règles de transformation directement dans la structure du document et pouvoir ainsi vérifier qu'ils sont conformes à la structure générique du document.
La figure 25 montre la construction de
l'instance cible par l'application des règles h1
,
C1
, h2
et C2
, et illustre le rôle
des noeuds de placement et des noeuds de construction.
h1
(présentée en mauve)
crée l'élément de placement dl et
l'élément de construction dt.
C1
(rouge
foncé) ne crée pas l'élément de placement
dl car c'est déjà le dernier élément du
niveau le plus haut de la structure du document cible, par contre
l'élément de placement dd est créé car il
ne correspond pas au type du dernier élément du second niveau de
structure (dt). L'étoile en fin de règle signifie que
l'élément p est copié dans la structure cible.
C1
(rouge clair) ne
génère pas de noeuds de placement car ceux-ci sont
déjà présents dans la branche la plus à droite de
la structure crée. Seul l'élément ol est
copié.
h2
(bleu
foncé) crée l'élément de placement dl et
l'élément de construction dt, tandis que la seconde ne
crée que l'élément dt ( l'élément
dl étant déjà créé par les
règles précédentes).
C2
copie les
éléments source (ul et table) dans la
structure cible.
|
|
structure source |
structure cible |
Figure 25 - Application des règles de transformation en liste titrée
Nous n'avons pas représenté sur la figure la descendance des éléments source. Cette descendance est simplement transférée depuis l'instance source dans les éléments correspondant dans l'instance destination. Par exemple, la descendance de h1 est transférée dans l'élément dt. Les éléments p, ol, ul et table ainsi que leur descendance sont transférés dans l'instance destination car les règles qui leur sont associées se terminent par le symbole '*'.
La transformation est effectuée par deux parcours de l'arbre de structure des éléments source. Le premier évalue les requêtes des différentes expressions de transformation, le second permet la génération des éléments de la structure cible.
Ces deux parcours sont rendus nécessaires pour laisser à l'utilisateur la possibilité de sélectionner une transformation après que la reconnaissance des requêtes a été effectuée et qu'un sous-ensemble des transformations a été pré-sélectionné. Cette interaction doit évidemment se faire préalablement à la phase de génération de l'instance cible. Dans le cas d'un appel induit, les deux parcours de la structure sont également effectués car l'algorithme de reconnaissance des requêtes effectue un parcours ascendant de l'arbre de structure de la source, tandis que la génération fait un parcours dans l'ordre préfixe, donc en descendant dans l'arbre de structure.
Le système de transformation d'Amaya a été conçu pour assister l'utilisateur dans l'élaboration de documents HTML. Alors que les autres éditeurs HTML ne proposent pas de commandes d'édition permettant la manipulation de structure, les transformations permettent à l'utilisateur de facilement structurer des documents faiblement structurés. Prenons l'exemple d'une liste que l'on voudrait changer en table : dans un éditeur quelconque il aurait fallu créer une table vide (éventuellement en spécifiant ses dimensions), et transférer un à un les contenus de chaque item de la liste dans les cellules de la table nouvellement créée. Avec Amaya, une seule transformation permet de changer une liste en table simplement en sélectionnant la liste à transformer et en cliquant sur l'icône table.
Les transformations dans Amaya se sont également avérées très utiles pour l'édition de formules mathématiques selon la DTD MathML [Ion 98]. Cette DTD XML est développée par le consortium W3C pour intégrer des formules mathématiques dans des pages Web. Les formules mathématiques MathML peuvent être très structurées : la figure 26 montre une formule mathématique et sa représentation MathML. Chaque opérateur est représenté par un (ou plusieurs) élément de structure, reflétant l'arbre syntaxique de la formule.
[Here is a formula] |
<msqrt> <mfrac> <mrow> <msup> <mi>x</mi> <mn>2</mn> </msup> <mo>+</mo> <msup> <mi>y</mi> <mn>2</mn> </msup> </mrow> <mn>2</mn> </mfrac> </msqrt> |
Figure 26 - Une formule mathématique et sa représentation MathML
La nature structurée des équations mathématiques est utile pour les applications interprétant la structure de ces équations, mais elle ne se prête pas facilement à l'édition. Par exemple, il est naturel pour un utilisateur de saisir le numérateur avant d'indiquer qu'il en train de saisir une fraction, ce comportement implique la création du contenu d'un élément avant de créer l'élément lui-même (ici la fraction). Il est nécessaire d'opérer une transformation de structure pour englober le numérateur dans l'élément fraction.
Amaya permet, grâce aux transformations, de sélectionner une expression mathématique et de choisir ensuite l'opérateur dans laquelle cette expression doit être insérée. Ce mode d'édition, combiné avec une palette contenant les opérateurs mathématiques permet une édition interactive des formules mathématiques reproduisant le schéma naturel de la rédaction.
Nous avons expérimenté le mécanisme de transformation d'Amaya dans l'éditeur Thot qui permet de manipuler des objets de diverses natures. L'objectif de cette expérience était d'évaluer l'apport de cette technique dans un environnement d'édition générique pour répondre à la problématique de cette thèse.
Cette expérience nous a montré que les transformations explicites ne sont pas adaptées aux environnements d'édition de documents structurés génériques. En effet, la transformation des éléments nécessite la spécification des transformations qui sont applicables à la DTD qui définit ces éléments. Les documents édités par Thot appartiennent à un ensemble de DTD susceptible d'augmenter au cours du temps. La réalisation d'un système de transformation complet pour un tel environnement passe par la spécification de transformation pour chacune des DTD utilisées, mais aussi en ces DTD. Sauf dans certains cas d'application très spécifiques, dans lesquels les transformations par filtre décrites au début de ce chapitre peuvent suffire, la définition des transformations devient alors une tâche trop importante comparativement à l'utilisation qui en est faite.
Après avoir présenté les méthodes de transformation explicites et les outils exploitant ces différentes méthodes ainsi que notre expérimentation de la transformation explicite, nous tirons des conclusions sur l'utilisation de cette approche dans notre problématique.
Les systèmes de transformation dirigés par la source sont performants (de l'ordre du nombre de noeuds de l'instance source). Cependant ce jugement doit être nuancé lorsque le contexte des éléments cibles doit être pris en compte. Le coût supplémentaire est minime lorsque seulement les frères précédents et ancêtres de l'élément (contexte gauche immédiat) doivent être considérés, cette information pouvant être conservée lors de l'application des règles précédentes. Le surcoût peut s'avérer important dès qu'un ensemble d'éléments constitue le contexte, principalement les éléments suivant l'élément en cours de transformation, ou la descendance de cet élément (contexte droit).
Les règles de transformation dépendantes du contexte posent des problèmes lors de l'implémentation du mécanisme de transformation :
Ce problème se pose pour les applications qui traitent le document comme un flot de données. C'est le cas des applications bâties sur un parser. Un outil qui stocke tout l'arbre du document en mémoire pour d'autres fonctions que la transformation peut accéder à tous les éléments de la structure sans nécessiter de mémoire supplémentaire.
Un autre point important en la défaveur des transformations dirigées par la source est qu'elles ne permettent pas de réaliser toutes les catégories de transformations. En particulier, elles ne permettent pas de mettre en oeuvre des transformations impliquant un ordonnancement différent des éléments dans la structure.
La transformation par requêtes nécessite une représentation de la structure d'un document en mémoire pour pouvoir appliquer des algorithmes de pattern-matching sur ces structures ([Kilpeläinen 92], [Cai 90], [Hoffmann 82]).
L'utilisation des requêtes pour la sélection d'une transformation ou d'un sous-ensemble des règles de transformations telles qu'elles sont utilisées dans XSL n'est pas pénalisante du fait de la localité des requêtes. Par contre, les requêtes permettant l'extraction d'information doivent traiter la structure entière du document à chaque évaluation, au détriment des performances du système d'évaluation de ces requêtes.
En contrepartie, des transformations complexes peuvent être réalisées en utilisant l'approche par requêtes, comme celles impliquant des déplacements d'éléments dans la structure des documents ou impliquant un changement dans l'ordre des éléments. Ces transformations ne peuvent pas être réalisées avec l'approche dirigée par la source et la génération linéaire.
Pour l'édition interactive, l'intérêt de l'approche par requête est la possibilité de sélection des règles à appliquer en fonction de la structure du document source. Ainsi, comme il a été montré dans le système de transformation d'Amaya, une même expression de transformation peut s'appliquer à un ensemble d'éléments n'ayant pas exactement la même configuration structurelle.
Le tableau de la figure 27 synthétise les caractéristiques des systèmes de transformation explicites étudiés :
Langage | Méthode deDirigée par la source | Requête action | Génération Linéaire | Arborescente | Applications | |||||
---|---|---|---|---|---|---|---|---|---|---|
IDM | C++ Script |
oui | oui (scripts) | non | oui | non | filtres de conversion | |||
Balise | Balise | oui | oui | non | non | sur place / nouveau | ||||
CoST 2 | Tcl | non | oui | non | oui | non | ||||
DSSSL | Scheme | non | non | oui | non | nouveau | formatage | |||
XSL | XML ECMA | oui (scripts) | non | oui | non | nouveau | formatage | |||
Chameleon | Graphique | non | oui | non | ||||||
Scrimshaw | Scrimshaw | non | non | oui | non | |||||
Amaya | trans | non | oui (ordre) | oui | non | sur place | édition interactive |
Figure 27 - Tableau comparatif des systèmes de transformation explicite.
La plupart des systèmes de transformation explicites nécessitent une expression extensive de la transformation des documents. C'est à dire que la spécification nécessite une description de la transformation de chacun des éléments du document source..
La déclaration des transformations entre documents structurés nécessite non seulement une connaissance de la syntaxe du langage de transformation, mais également la connaissance des DTD source et cible. Cependant, la plupart des outils de transformation ne vérifient pas la conformité du document produit par rapport à sa DTD. Parmi les systèmes présentés, seul Amaya, qui est un environnement d'édition basé sur la syntaxe, Balise, qui est une bibliothèque de développement d'applications utilisant les documents structurés, et Chameleon, qui permet de spécifier des transformations à partir d'une représentation sous forme de grammaire des DTD, vérifient la conformité du document cible avec son modèle.
Notre objectif est de proposer un service de transformation de documents structurés prenant en compte la validité du document cible par rapport à sa DTD. Cette caractéristique est à notre sens essentielle pour un système de transformation. En effet, l'édition de documents structurés utilise des mécanismes qui se fondent sur la structure et qui supposent que les documents sont conformes à leur structure générique.
Lors de la création d'éléments comme lors de la transformation d'éléments, la conformité d'un document dépend non seulement de son type, de celui de son père et de ses frères, mais en plus, les mécanismes d'inclusion, d'exclusion (au sens SGML) et d'héritage impliquent que la validité d'une instance dépende du contexte du document entier. Ainsi, il n'est pas possible de décider de la validité d'une transformation à partir de sa seule spécification. Par conséquent, la validité des éléments insérés ne peut être vérifiée par le système que lorsque la transformation est effectuée.
Nous abordons dans le chapitre suivant une approche plus formelle du modèle de documents structurés. Nous définissons clairement ce que sont les types d'éléments que nous manipulons et les relations entre ces types qui seront utilisées pour la transformation. Ainsi nous pourrons proposer un système de transformation de basant sur les structures génériques des types d'éléments nous garantissant par construction la validité de la structure des éléments crées.
Notre objectif n'est pas seulement de proposer des transformations garantissant le maintien de la validité du document, mais aussi de s'appuyer sur les relations entre les types des éléments concernés pour proposer un mécanisme de transformation automatique.