• Aucun résultat trouvé

2.4 Les techniques et les outils de transformation

2.4.3 Le langage Circus

Circus [220, 223, 219, 183] est un langage de programmation spécialisé dans la manipulation de structures de données, et est en ce sens adapté à la manipulation de documents XML, même s’il ne se limite pas uniquement à ce type de structures. Le langage fournit les constructions et opérations communément proposées par les langages généralistes (opérations mathématiques, de manipulation de chaînes, abstractions procédurales, etc.), mais aussi des constructions programmatiques comme le filtrage structurel et un système de types très riche. Ainsi, Circus se positionne, dans le monde XML, à un niveau d’abstraction intermédiaire entre XSLT et des solutions de plus bas niveau telles que DOM combiné à un langage généraliste comme Java. Nous détaillons certaines constructions du langage, que nous utiliserons par la suite puisque Circus est une des deux cibles possibles pour l’exportation des programmes exprimés avec notre langage visuel (VXT).

Système de types

Circus propose un système de types incluant des types de données primitifs (booléens, chaînes de ca-ractères, nombres entiers et flottants) ainsi que des types structurés (multi-ensembles, séquences, tuples, enregistrements et dictionnaires), des types énumérés et des types récursifs. Il est d’autre part possible de définir de nouveaux types par l’union de types existants (opérateur |).

La figure 2.8 contient les déclarations de types permettant de modéliser les structures XML. Le type principal est XMLTree, un type récursif formé par une union de types. Il permet de modéliser les éléments non vides attribués (ligne 5), les éléments non vides sans attribut (ligne 6), les éléments vides attribués (ligne 7), les éléments vides sans attributs (ligne 8) et les autres nœuds terminaux (ligne 9), à savoir les nœuds texte (PCdata et Cdata), les commentaires, et les processing instructions. Le champ label contient le nom de l’élément, le champ attr est un dictionnaire contenant les attributs (couples nom-valeur), et le champ sub est une séquence de nœuds représentant le contenu de l’élément. Il sera possible de déclarer des variables typées au moyen du mot-clé var (lignes 11 à 13, qui représentent un fragment de l’instance de document DocBook de la figure 2.2).

13. hlabel=’section’, sub=[...] i ]i.

FIG. 2.8 : Modélisation des structures XML en Circus

Ce modèle a fortement évolué depuis l’introduction des références dans le langage ; nous présentons cependant ici la première version car VXT repose pour l’instant sur celle-ci. Nous mentionnons sim-plement l’extension, dans la nouvelle version [220], du système de types, qui permet de modéliser les contraintes structurales des DTD simplement à l’aide de types Circus11. La vérification de ceux-ci dans un programme se faisant de manière statique, cela signifie que l’utilisation, dans un programme de trans-formation, de sous-types de XMLTree modélisant les contraintes des DTD des documents source et cible, permet de garantir, s’il n’y a pas d’erreur de compilation du programme, la validité (au sens XML) des documents produits. Cette propriété est jugée de plus en plus importante, permettant de garantir la qua-lité des traitements appliqués aux documents et des résultats de ces traitements (voir l’introduction de J. Clark à la conférence XML 2001 [54] et le sujet de plusieurs articles présentés au workshop Plan-X [229]). Elle représente cependant un problème complexe et n’est offerte ni par XSLT, ni par les solu-tions utilisant DOM. À notre connaissance, les deux seuls autres langages proposant de modéliser les contraintes structurales des schémas afin de garantir la validité des documents engendrés par la transfor-mation sont XDuce [121] et XSLT0 [210], qui n’est malheureusement qu’un sous-ensemble de XSLT et dont l’intérêt en tant que langage de transformation est limité. Le nouveau système de types Circus offre cette possibilité, dans le cadre d’un ensemble de composants de traitement de schémas appelé D-TaToo (Document Type Analysis and Transformation Toolkit), dont font aussi partie des composants de transformation de DTD réalisés dans le cadre de ce travail : l’analyseur de DTD Circus et DTD2HTML, un programme qui facilite la lecture d’une DTD par l’expansion des entités paramètres (internes et ex-ternes), l’ajout d’une vue inversée indiquant pour chaque élément la liste des éléments dans lesquels ils sont autorisés, et l’enrichissement du document ainsi obtenu par des liens hypertextes pour faciliter la navigation entre les éléments et attributs définis par la DTD.

Règles et opérations de filtrage

Circus autorise la combinaison d’instructions impératives et d’expressions déclaratives (imperative and declarative statements). Les instructions elles-mêmes sont évaluées lors de l’exécution, et retournent

11Les contraintes structurales exprimées dans les DTD sont toutes capturées ; ce n’est par contre pas le cas pour les XML

Schema qui offrent des contraintes beaucoup plus riches ; la nouvelle version de Circus offre cependant une couverture plus

Les techniques et les outils de transformation 43 les valeurs unit ou none suivant qu’elles réussissent ou non. Ainsi, une règle, de la forme générale b → e avec b une expression booléenne et e n’importe quelle expression appartenant au langage, retournera soit unit si b est évaluée à vrai, soit none si b est évaluée à faux ; une instruction impérative retournera quant à elle toujours unit. La partie gauche des règles Circus peut contenir une expression de filtrage à la place de l’expression booléenne. Ces règles sont de la forme

e1#f → e2

avec e1 n’importe quelle expression du langage retournant une valeur, f un filtre et e2n’importe quelle expression appartenant au langage. Le filtre f est appliqué à e1, appelé le sujet de l’expression de filtrage. Si l’application du filtre sur la valeur retournée par e1réussit, e2est évaluée et sa valeur est retournée ; si elle échoue, la valeur none est retournée12.

Les filtres sont des expressions modélisant des contraintes de sélection sur la structure et le contenu des sujets, mais aussi des instructions d’extraction d’une partie ou de la totalité du contenu de ces su-jets. Les filtres adoptent une syntaxe proche de celle des constructeurs de valeurs. Nous adopterons une approche similaire dans le cadre de VXT, en proposant des expressions de filtrage (les VPMEs, Visual Pattern Matching Expressions) visuellement proches des structures qu’elles sélectionnent. La construc-tion des filtres s’en trouve ainsi facilitée. Nous donnons ici les principales construcconstruc-tions utilisées dans les filtres. ? est un test d’existence, ?x vérifie l’existence dans le sujet d’une donnée du type de la variable xet stocke13cette donnée dans x, %e évalue l’expression e et vérifie que le sujet a la même valeur. Les filtres structurés utilisent les mêmes constructions syntaxiques que les structures de données ([ ] pour les séquences, 0 0 pour les chaînes de caractères, { } pour les multi-ensembles et { = } pour les diction-naires). Ces filtres basiques et structurés peuvent être combinés au moyen de l’opérateur d’agrégation ++considéré comme le dual de l’opérateur de concaténation + et qui s’applique comme lui aux chaînes de caractères, séquences, multi-ensembles et dictionnaires. L’opérateur && a la même sémantique mais ne tient pas compte de l’ordre des éléments lors de la sélection. Différents filtres peuvent d’autre part être combinés dans une même règle au moyen des opérateurs booléens and et or. Nous donnons quelques exemples concrets d’expressions de filtrage :

0circus0# ?x++%0rc0++?réussit à condition que la variable x soit de type chaîne (String) et lui assigne la valeur ci,

[1, 2, 3] # [%1]++?xréussit et assigne la séquence [2, 3] à x ,

hlabel =0title0, sub = [0Animations in XV T M0]i # hlabel = %0title0, sub =?childreniréussit à condition que children soit de type (ou bien un sous-type de) [XMLTree] et stocke le contenu de l’élément title dans la variable children,

hlabel =0section0, sub = [hlabel =0para0, sub = [0sometext0]i] #

hlabel = %0section0, sub =? + +[hlabel = %0title0i] + +? échoue car l’élément section ne contient pas d’élément title,

hlabel =0articleinf o0, sub = [hlabel =0date0, sub = [022 M ay 20020]i]i # hlabel = %0articleinf o0i and ?xréussit si la variable x est de type (ou bien un sous-type de) XMLTree et stocke le sujet complet dans cette variable.

12Retourner la valeur de e2correspond donc informellement à retourner unit.

[|e1, ..., en|]

où ei représente une expression appartenant au langage, et peut notamment être une règle de filtrage, de la forme

ei1# f → ei2

L’exécution d’un système d’actions [|e1, ..., en|]consiste alors à évaluer les expressions ei dans l’ordre jusqu’à la première ne retournant pas none, c’est-à-dire la première règle qui réussit.

Circus propose aussi plusieurs constructions permettant d’exprimer des boucles itératives. Nous utili-serons dans le cadre de VXT la boucle for, notée

for el in aSet do (insts)

où el désigne la variable d’itération sur l’ensemble aSet parcouru du premier au dernier élément (il peut s’agir d’une séquence ou d’un multi-ensemble), et insts un ensemble d’instructions impératives et déclaratives éventuellement combinées en un système d’actions qui est exécuté à chaque itération.

Machines abstraites polymorphes et λ-fonctions

Le langage offre deux sortes d’abstractions procédurales : les λ-fonctions et les PAM (Polymorphic Abstract Machines). Les λ-fonctions sont de la forme

const aF unction : t1 → t2 =lambda x : t1.insts

où aFunction est le nom de la fonction, x le paramètre d’entrée de type t1et insts un ensemble d’instruc-tions impératives et déclaratives. Cet ensemble d’instrucd’instruc-tions doit s’évaluer en une valeur de type t2, qui sera retournée par la fonction.

Enfin, les PAM sont des sortes de procédures ayant un paramètre d’entrée et un paramètre de sortie, tous les deux typés. Circus fournit un mécanisme innovant pour la composition de PAM que nous ne détaillons pas ici car nous n’en ferons pas usage dans le cadre de VXT (voir [223] pour une description des PAM et du mécanisme de composition).

Conclusion 45 Le fragment de code ci-dessous donne un équivalent en Circus de la deuxième règle de la transforma-tion XSLT présentée dans la figure 2.7 (lignes 9 à 11) : node est une variable de type XMLTree contenant le nœud par rapport auquel sont évaluées les règles de transformation, et la variable res contient la struc-ture résultat. La fonction XValue est équivalente à l’instruction value−of de XSLT. Un exemple de programme Circus complet, contenant la définition de la fonction XValue, est donné dans la figure A.2 de l’annexe A (cet exemple correspond à la transformation développée dans le chapitre 4).

node # h label=%’mml:ci’ i → res := res + [h label=’mml:mi’, sub=XValue(node.sub) i]

2.5 Conclusion