Brevet FR2925192A1 — publié le 20090619

La présente invention concerne un procédé et un dispositif de génération d'expressions et de documents. XML (acronyme de Extensible Markup Language, c'est à dire langage de balisage extensible) est une syntaxe pour définir des langages informatiques. XML permet ainsi de créer des langages adaptés à des utilisations différentes mais pouvant être traités par les mêmes outils. Un document XML est composé d'éléments, chaque élément commençant par une balise ouvrante comportant le nom de l'élément (par exemple, ) et se terminant par une balise fermante comportant elle aussi le nom de l'élément (par exemple, ). Chaque élément peut contenir d'autres éléments ou des données textuelles. Par ailleurs, un élément peut être précisé par des attributs, chaque attribut étant défini par un nom et ayant une valeur. Les attributs sont placés dans la balise ouvrante de l'élément qu'ils précisent (par exemple: ). La syntaxe XML permet aussi de définir des commentaires (par exemple, � �) et des instructions de traitement, qui peuvent préciser à une application informatique quels traitements appliquer au document XML (par exemple, � �). Les différents composants d'un document XML, éléments, attributs, valeurs textuelles, commentaires et instructions de traitement peuvent être 25 regroupés sous le terme générique de � noeud �. Plusieurs langages XML différents peuvent contenir des éléments de même nom. Pour pouvoir mélanger plusieurs langages XML différents, un ajout a été effectué à la syntaxe XML permettant de définir des espaces de nommage (� Namespace �, en anglais). Deux éléments sont identiques 30 seulement s'ils ont le même nom et se trouvent dans le même espace de nommage. Un espace de nommage est défini par une URI (acronyme de � Uniform Resource Identifier �, pour identifiant de ressource uniforme), par exemple � http://canon.crf.fr/xml/monlangage �. L'utilisation d'un espace de nommage dans un document XML passe par la définition d'un préfixe qui est un raccourci vers l'URI de cet espace de nommage. Ce préfixe est défini à l'aide d'un attribut spécifique (par exemple, � xmins:ml="http://canon.crf.fr/xml/ monlangage" � associe le préfixe � ml � à l'URI � http://canon.crf.fr/xml/ monlangage �). Ensuite, l'espace de nommage d'un élément ou d'un attribut est précisé en faisant précéder son nom par le préfixe associé à l'espace de nommage suivi de � : � (par exemple, � �). XPath est une syntaxe pour désigner une portion d'un document XML. Cette syntaxe a été développée à l'origine pour fournir une base commune à différentes applications traitant des documents XML (par exemple XSLT, XQuery). Le coeur de la syntaxe XPath est constitué par les chemins de localisation qui définissent un ensemble de noeuds XML et les relations entre ces noeuds. Ainsi le chemin � /a/b � désigne l'ensemble des éléments � b � fils d'un élément � a � racine du document XML. Un chemin de localisation est ainsi constitué d'un ensemble d'étapes, chaque étape précisant un axe, un test de noeud et, éventuellement, un ensemble de prédicats. L'axe permet de définir la relation entre l'étape courante et l'étape précédente. Par défaut, si l'axe n'est pas précisé, l'étape courante concerne les enfants directs des noeuds sélectionnés par l'étape précédente. D'autres axes existent, permettant de naviguer facilement dans l'ensemble du document XML. Ainsi le chemin � /a/descendant::b � désigne l'ensemble des éléments � b � descendants, avec une quelconque profondeur, d'un élément � a � racine du document XML. A l'inverse, le chemin � b/ancestor::a � désigne l'ensemble des éléments � a � ancêtre (avec une quelconque profondeur) d'un élément � b � enfant de l'élément courant. Selon un autre exemple, le chemin � /descendant::a/following::b � désigne l'ensemble des éléments � b � suivant un élément � a � situé à une quelconque profondeur dans le document. Un axe spécifique permet de désigner les attributs d'un élément. Ainsi � /a/attribute::b � retourne l'attribut � b � de l'élément � a � racine du document XML. Les axes peuvent être séparés en deux catégories : les axes � vers l'avant � (en anglais, � forward axis �), qui décrivent des relations dans l'ordre du document et les axes � vers l'arrière � (en anglais, � reverse axis �), qui décrivent des relations inverses à l'ordre du document. Le test de noeud permet de préciser les caractéristiques des éléments recherchés. Le test le plus simple est constitué par le nom des noeuds à rechercher. Ainsi � /descendant::a � retourne l'ensemble des éléments � a � du document. Un test générique permet d'obtenir tous les noeuds quel que soit leur nom. Ainsi � /descendant::* � retourne l'ensemble des éléments du document. Enfin, un test sur le type du noeud permet de ne retourner que les noeuds d'un type défini. Ainsi � /descendant::comment() � retourne l'ensemble des commentaires du document. Les prédicats permettent de définir des conditions sur les noeuds désignés par l'étape. Ces conditions peuvent prendre la forme d'une position, ainsi l'expression � /a/b[2] � désigne le deuxième élément � b � fils de l'élément racine � a �. Elles peuvent aussi prendre la forme d'un test � /a/b[c] � désigne l'ensemble des éléments � b � fils de l'élément racine � a � et ayant un élément fils � c �. Les conditions peuvent aussi vérifier le contenu d'un élément ou d'un attribut. Ainsi l'expression � /a/b[c="valeur"] � désigne l'ensemble des éléments � b � fils de l'élément racine � a � ayant un élément fils � c � dont la valeur textuelle est � valeur �. De façon similaire, l'expression � /a/b[@c="valeur"] � désigne l'ensemble des éléments � b � fils de l'élément racine � a � ayant un attribut � c � dont la valeur est � valeur �. Une étape d'un chemin de localisation peut comporter plusieurs prédicats. Ces prédicats sont appliqués successivement pour sélectionner les éléments désignés par l'étape. Ainsi l'expression � /a/b[c][2] � désigne le deuxième élément � b � qui est fils de l'élément racine � a � et qui a un élément fils � c �. En général, l'ordre des prédicats est important. Ainsi l'expression � /a/b[2][c] � est différente de l'expression précédente, désignant le deuxième élément � b � fils de l'élément racine � a � et vérifiant en outre que cet élément a un élément fils � c �. En plus des chemins de localisation, la syntaxe XPath contient un ensemble d'expressions algébriques et de comparaison (utiles pour exprimer les prédicats) ainsi qu'un ensemble de fonctions (pour exprimer des prédicats ou traiter l'ensemble d'éléments désignés par un chemin de localisation). Lors du développement d'une implémentation XPath, il est important de tester celle-ci pour vérifier qu'elle est bien conforme à la norme. Comme XPath est un langage de requêtes, ou expressions, sur des documents XML, un jeu de tests doit comporter une expression XPath à évaluer et un document XML sur lequel l'expression XPath est évaluée. Il est évidemment possible de combiner les jeux de tests, une expression XPath pouvant être évaluée sur plusieurs documents XML, ou plusieurs expressions XPath pouvant être évaluées sur un même document XML. Le principal problème qui se pose est celui de la génération des jeux de tests. En effet, il est possible d'écrire à la main des jeux de tests, mais comme le langage XPath est riche, le nombre de points à tester est important : il faut ainsi tester chaque axe de localisation, chaque test de noeud, chaque fonction, chaque opérateur algébrique... En outre, il est intéressant de tester différentes combinaisons de ces différents points. Par exemple, au niveau des opérateurs algébrique, il convient de vérifier que les règles de priorité sont bien respectées. Enfin, chaque point ou combinaison de points à tester doit l'être dans un ensemble de cas représentatifs. Pour réaliser un test extensif d'une implémentation XPath, il est donc nécessaire d'écrire un nombre très important de jeux de tests, ce qui est difficilement réalisable manuellement. Pour créer un ensemble de tests extensif pour une implémentation XPath, il est donc nécessaire d'utiliser des procédures automatiques de génération de jeux de tests. La génération automatique de jeux de tests est un domaine déjà connu. En particulier, elle est utilisée pour tester des compilateurs de langage de programmation. Dans un tel cas, les jeux de tests sont créés à partir de la grammaire décrivant le langage de programmation. Le document US 5,913,023 décrit une méthode de génération automatique de test pour des logiciels. Cette méthode utilise des grammaires pour construire les jeux de tests. En outre, des contraintes sont utilisées pour préciser les jeux de tests. Ces contraintes permettent de préciser quelles parties de la grammaire doivent être couvertes par les jeux de tests. Ces contraintes permettent aussi de sélectionner les jeux de tests générés, ou de limiter le nombre de jeux de tests générés. Le document US 5,754,860, décrit une méthode de test de logiciel utilisant des techniques de test différentiel pour tester de compilateurs. Cette méthode utilise, elle aussi, des grammaires pour construire les jeux de tests. En outre, cette méthode utilise des contraintes pour préciser les jeux de tests à construire. Le rôle de ces contraintes est de décrire des aspects du langage à tester qui ne sont pas décrits par la grammaire du langage. Ainsi, dans l'exemple du langage C, une variable doit être définie avant d'être utilisée. Ceci n'est pas décrit par la grammaire du langage C, mais peut être précisé à l'aide d'une contrainte. Dans cette méthode, l'utilisation des contraintes permet d'éviter de générer des jeux de tests non-conformes à la spécification du langage et donc peu utiles dans la vérification de la conformité du compilateur. Le principal problème des méthodes de génération automatique de jeux de tests à partir d'une grammaire est qu'elles ne s'appliquent pas facilement à la problématique du langage XPath. En effet, ces méthodes permettent de générer des expressions XPath à partir de la grammaire du langage XPath. Elles permettent aussi de générer des documents XML à partir de la grammaire du langage XML. Mais les expressions XPath et les documents XML générés le sont indépendamment. Or, pour tester un point de la norme XPath, il est nécessaire que, non seulement, l'expression XPath générée concerne ce point (par exemple, que l'expression XPath comporte un test de noeud portant sur le nom du noeud), mais aussi que le document XML généré corresponde à ce point de la norme XPath (par exemple, un premier document XML peut comporter un noeud possédant le nom recherché par l'expression XPath, tandis qu'un deuxième document XML peut comporter un noeud possédant un nom différent de celui recherché). Les solutions existantes ne sont donc pas adaptées à la génération de test automatique pour la norme XPath, elles permettent, tout au plus, de tester un compilateur XPath (c'est-à-dire un logiciel qui prend en entrée une expression XPath, vérifie qu'elle est correcte et en génère une représentation interne apte à être évaluée sur un document XML), mais ne permettent pas de tester correctement l'ensemble de l'évaluateur XPath. La présente invention vise, en particulier, à résoudre ce problème et à fournir une méthode de génération de jeux de tests à partir d'une grammaire pour générer simultanément des expressions XPath et des documents XML associés pertinents. A cet effet, selon un premier aspect, la présente invention vise un procédé de génération de jeux de test, caractérisé en ce qu'il comporte : - une étape d'obtention d'un jeu de règles de grammaire décrivant un 10 premier langage, - une étape d'obtention d'au moins un jeu de contraintes liées aux dites règles de grammaire décrivant le premier langage, - une étape de génération d'au moins une expression dans le premier langage, en mettant en oeuvre lesdites règles de grammaire décrivant 15 le premier langage et - une étape de génération d'un document dans un deuxième langage, en appliquant au moins un jeu de contraintes audit document. Ainsi, quand toutes les règles de grammaire, et donc tous les jeux de contraintes associés à une expression ont été sélectionnés, l'ensemble des 20 contraintes est appliqué pour générer le document. La présente invention résout ainsi le problème mentionné ci-dessus en réalisant la génération de jeux de tests à partir d'une grammaire et, simultanément, des expressions (par exemple, des expressions XPath) et des documents (par exemple, des documents XML) associés pertinents. 25 Selon des caractéristiques particulières, le procédé objet de la présente invention, tel que succinctement exposé ci-dessus comporte, avant l'étape d'obtention d'au moins un jeu de contraintes, une étape de sélection d'un ensemble de règles de grammaire du premier langage dites � de dérivation �, et en ce que les règles de dérivation sont utilisées au cours de 30 l'étape d'obtention d'au moins un jeu de contraintes et au cours de l'étape de la génération d'au moins une expression dans le premier langage. Ainsi, les contraintes appliquées pour générer le document (par exemple, le document XML) correspondent aux règles utilisées pour générer l'expression (par exemple l'expression XPath) et le document est donc pertinent pour tester l'expression. Selon des caractéristiques particulières, au cours de l'étape de génération d'un document, chaque partie du document qui n'est pas complètement définie par lesdites contraintes, est complétée de manière aléatoire. Selon des caractéristiques particulières, au cours de l'étape de génération d'au moins une expression, au moins une dite expression est une expression XPath. Selon des caractéristiques particulières, au cours de l'étape de génération de documents, on génère des documents XML. Selon des caractéristiques particulières, au cours de l'étape de génération d'au moins une expression, la grammaire est réduite et ne comprend qu'une partie de la définition du premier langage. Ainsi, les tests générés correspondent à un aspect particulier du langage. Selon des caractéristiques particulières, au cours de l'étape de génération d'au moins une expression, la syntaxe du premier langage est définie à partir de symboles, chaque symbole étant défini à partir d'un ensemble de règles de grammaire dites � de dérivation � qui expriment l'ensemble des possibilités autorisées par le premier langage pour ce symbole à partir d'autres symboles et de chaînes de caractères. Selon des caractéristiques particulières, au moins un jeu de contraintes est associé à une règle de dérivation. Selon des caractéristiques particulières, au cours de l'étape de génération d'au moins une expression dans le premier langage, on sélectionne un ensemble de règles de dérivation de ladite grammaire pour produire une expression dans le premier langage, en sélectionnant un symbole initial, puis en réalisant des dérivations jusqu'à ce que l'expression ne contienne plus aucun symbole pouvant être dérivé. Selon des caractéristiques particulières, les contraintes sont appliquées successivement à un ensemble de noeuds courants du document dans le deuxième langage. Ainsi, les contraintes peuvent correspondre à diverses parties du 5 document généré. Selon des caractéristiques particulières, le procédé objet de la présente invention, tel que succinctement exposé ci-dessus met en oeuvre des ensembles indépendants de jeux de contraintes, un ensemble de noeuds courants restant inchangé après application d'un ensemble indépendant de jeux 10 de contraintes. Ainsi, plusieurs ensembles de jeux de contraintes correspondant à plusieurs sous-expressions de l'expression générée dans le premier langage peuvent être appliqués indépendamment et générer, pour chaque sous-expression, une partie pertinente dans le document généré. 15 Selon des caractéristiques particulières, ledit jeu de contraintes comporte au moins une contrainte de test. Selon des caractéristiques particulières, au moins une dite contrainte de test concerne une profondeur, un nom, une valeur, un type et/ou un espace de nommage pour au moins l'un des noeuds courants. 20 Ainsi, il est possible de sélectionner ou non un noeud courant en fonction de ses caractéristiques. Les contraintes de test permettent de conserver ou non un noeud courant dans l'ensemble des noeuds courants. Selon des caractéristiques particulières, ledit jeu de contraintes comporte au moins une contrainte de génération. 25 Selon des caractéristiques particulières, au moins une contrainte de génération concerne un chemin, un nom, une valeur, un type, un espace de nommage et/ou une définition de variable pour au moins l'un des noeuds courants. Ainsi, il est possible de générer de nouveaux noeuds correspondant 30 à de nouvelles parties du document, ou de préciser certaines caractéristiques d'un noeud déjà existant. Selon des caractéristiques particulières, au cours de l'étape de génération d'un document dans un deuxième langage, en appliquant le jeu de contraintes audit document, un document XML est créé en appliquant successivement chaque jeu de contraintes associé à une règle de grammaire. Selon des caractéristiques particulières, ledit document XML est créé en appliquant, au sein d'au moins un jeu de contraintes comportant des contraintes de test et des contraintes de génération, d'abord les contraintes de test et, ensuite, les contraintes de génération. Ainsi, dans un premier temps, une partie du document est sélectionnée par les contraintes de tests, à partir de l'ensemble des noeuds courants, puis, dans un deuxième temps, cette partie du document est étendue ou précisée par les contraintes de génération. Selon un deuxième aspect, la présente invention vise un dispositif de génération de jeux de test, caractérisé en ce qu'il comporte : - un moyen d'obtention d'un jeu de règles de grammaire décrivant un premier langage, - un moyen d'obtention d'un jeu de contraintes liées aux dites règles de grammaire décrivant le premier langage, - un moyen de génération d'au moins une expression dans le premier langage, en mettant en oeuvre lesdites règles de grammaire décrivant le premier langage et - un moyen de génération d'un document dans un deuxième langage, en appliquant le jeu de contraintes audit document. Selon un troisième aspect, la présente invention vise un programme d'ordinateur chargeable dans un système informatique, ledit programme contenant des instructions permettant la mise en oeuvre du procédé de génération d'expressions et de documents objet de la présente invention tel que succinctement exposé ci-dessus. Selon un quatrième aspect, la présente invention vise un support d'informations lisibles par un ordinateur ou un microprocesseur, amovible ou non, conservant des instructions d'un programme informatique, caractérisé en ce qu'il permet la mise en oeuvre du procédé de génération d'expressions et de documents objet de la présente invention tel que succinctement exposé ci-dessus. Les avantages, buts et caractéristiques de ce dispositif de génération de jeux de tests, de ce programme d'ordinateur et de ce support d'information étant similaires à ceux du procédé de génération de jeux de tests objet de la présente invention, tel que succinctement exposé ci-dessus, ils ne sont pas rappelés ici. D'autres avantages, buts et caractéristiques de la présente invention ressortiront de la description qui va suivre, faite, dans un but explicatif et nullement limitatif en regard des dessins annexés dans lesquels : - la figure 1 représente, sous forme d'un logigramme, des étapes mises en oeuvre dans un mode de réalisation particulier du procédé objet de la présente invention, - la figure 2 représente, sous forme d'un logigramme, des étapes mises en oeuvre pour, dans le mode de réalisation illustré en figure 1, sélectionner des règles de dérivation, des jeux de contraintes et pour générer l'expression XPath, - la figure 3 représente, sous forme d'un logigramme, des étapes mises en oeuvre pour, dans le mode de réalisation illustré en figure 1, dériver un 20 symbole de la grammaire, - la figure 4 représente, sous forme d'un logigramme, des étapes pour, dans le mode de réalisation illustré en figure 1, dériver l'ensemble des symboles non-terminaux contenus dans une règle de dérivation, - la figure 5 représente, sous forme d'un logigramme, des étapes 25 pour, dans le mode de réalisation illustré en figure 1, générer un document XML à partir d'une liste de jeux de contraintes, - la figure 6 représente, sous forme d'un logigramme, des étapes pour, dans le mode de réalisation illustré en figure 1, appliquer des contraintes de test lors de la génération d'un document XML, 30 - la figure 7 représente, sous forme d'un logigramme, des étapes pour, dans le mode de réalisation illustré en figure 1, appliquer des contraintes de génération lors de la génération d'un document XML et - la figure 8 représente, schématiquement, un mode de réalisation particulier d'un dispositif objet de la présente invention. Dans le mode de réalisation décrit en regard des figures, appliqué à la génération d'expressions XPath et de documents XML, on génère les expressions XPath comme dans l'art antérieur à partir de la grammaire décrivant le langage XPath et on génère, pour chaque expression XPath, un ou plusieurs documents XML liés à cette expression XPath. Chacun de ces documents XML est créé à partir de contraintes liées aux règles de la grammaire XPath. Ces contraintes sont d'au moins deux types, les contraintes de test et les contraintes de génération, comme exposé plus loin. A chaque fois qu'une règle de grammaire est sélectionnée dans la génération de l'expression XPath, si cette règle de grammaire possède un ou plusieurs jeux de contraintes associés, l'un de ces jeux est sélectionné pour entrer dans la définition du document XML. Quand un ensemble de règles de grammaire permettant de générer une expression XPath a été sélectionné, alors l'ensemble des jeux de contraintes sélectionnés simultanément est appliqué pour générer le document XML. On sélectionne ainsi un ensemble de règles de grammaire et, simultanément, un ensemble de jeux de contraintes en sélectionnant, pour chaque règle de grammaire sélectionnée, un seul des jeux de contraintes associés à cette règle. On ne génère le document XML qu'après avoir fini la sélection de l'ensemble de jeux de contraintes. Si certaines parties du document XML ne sont pas complètement définies par les contraintes, ces parties sont complétées de manière aléatoire. Comme exemple d'application de l'invention, on peut considérer la grammaire suivante, qui est une forme réduite (à l'extrême) de la grammaire XPath : 1. Path = "/" Step 2. Step = AxisName "::" NameTest 3. AxisName = "child" 4. NameTest = NCName 5. NCName = "target" Cette grammaire permet de générer une seule expression XPath : /child::target Cette expression recherche tous les éléments nommés � target � enfants directs de la racine du document. Pour la génération des documents XML, plusieurs jeux de contraintes sont associés à cette grammaire. Pour la règle 5, deux jeux de contraintes sont associés : name = "target" name = "other" Ces deux jeux de contraintes contiennent chacun une contrainte portant sur le nom du noeud courant (contrainte de type � name �). Cette contrainte définit le nom du noeud courant. Le premier jeu définit le nom de l'élément courant comme étant égal à � target �, c'est-à-dire le nom recherché par la règle 5 de la grammaire. Au contraire, le deuxième jeu définit le nom de l'élément courant comme � other �, c'est-à-dire avec un nom différent de celui recherché par la règle 5 de la grammaire. Ainsi les deux jeux de contraintes permettent de tester les deux cas par rapport au test de noeud : celui où le nom recherché est présent dans le document XML et celui où le nom recherché est absent du document XML. A la règle 3, sont associés les deux jeux de contraintes suivants : path = c path = cc Le premier jeu de contraintes, contient une contrainte de navigation qui porte sur la localisation du noeud courant dans le document XML (contrainte de type � path �). Cette contrainte, dont la valeur est � c � indique qu'il faut naviguer depuis le noeud courant vers son premier élément fils. Initialement, le noeud courant du document XML est le document lui-même. Les contraintes de navigation permettent de changer ce noeud courant. Une contrainte de navigation a pour effet de créer le nouveau noeud courant dans le document XML sans le préciser. D'autres contraintes pourront préciser certaines caractéristiques de ce noeud courant. De manière similaire, le deuxième jeu de contraintes contient une contrainte indiquant qu'il faut naviguer depuis le noeud courant vers le premier enfant de son premier enfant. Comme pour le cas de la règle 5, les deux jeux de contraintes permettent de tester deux cas par rapport à l'axe de localisation défini par la grammaire : le premier jeu permet de naviguer, au sein du document XML, à la position recherchée par l'expression XPath, tandis que le deuxième jeu permet de naviguer à une autre position. L'ensemble de ces jeux de contraintes permet de générer 4 10 documents XML (2*2 jeux de contraintes). Document 1-1: Document 1-2: 15 Document 2-1: 20 Document 2-2: 25 Seul le � Document 1-1 � contient un résultat pour l'expression XPath : il combine les deux jeux de contraintes correspondant à l'expression XPath. Les autres documents correspondent à différents cas où l'expression 30 XPath ne doit pas retourner de résultat. Il est à noter que les éléments notés � node-O � ont été complété de manière pseudo-aléatoire par le générateur, car ils n'étaient précisés par aucune contrainte. En effet, la contrainte � path = cc � crée deux noeuds : le premier fils du noeud courant et le premier fils de ce premier fils. Seul ce deuxième noeud est précisé par une contrainte de type � name �. La complétion est réalisée de manière pseudo-aléatoire pour éviter que le nom complété corresponde à une valeur se trouvant dans la grammaire utilisée pour la génération XPath. Comme illustré en figure 1, pour la génération d'un jeu de tests, une première étape 100 consiste à obtenir la grammaire décrivant les jeux de tests à générer. Cette grammaire comporte, d'une part, la définition du langage de requêtes ou expressions, XPath ici, et, d'autre part, la définition des contraintes permettant de générer les documents sur lesquels porteront les expressions, XML ici. La grammaire peut être réduite et ne comprendre qu'une partie de la définition du langage d'expressions afin de réduire le nombre de jeux de tests générés, ou pour produire un ensemble de jeux de tests spécialisés pour une partie du langage de requête. Un exemple de grammaire pour le langage XPath et des documents XML est décrit ci-dessous. Une grammaire peut être décrite, par exemple, en utilisant une notation comme la notation � Backus-Naur form � (� BNF �). Dans cette notation, la syntaxe du langage est définie à partir de symboles, chaque symbole étant défini à partir d'un ensemble de règles de dérivation. Ces règles de dérivation d'un symbole permettent d'exprimer l'ensemble des possibilités autorisées par le langage pour ce symbole à partir d'autres symboles et de chaînes de caractères. En outre, à certaines règles de dérivation sont associées des jeux de contraintes permettant de définir le document XML à générer. Puis, au cours d'une étape 110, on sélectionne un ensemble de règles de dérivation de la grammaire pour produire une expression dans le langage XPath. Cette sélection s'effectue de manière classique pour une grammaire BNF en sélectionnant un symbole initial comme exposé en regard de la figure 2, puis en réalisant des dérivations jusqu'à ce que l'expression ne contienne plus aucun symbole pouvant être dérivé. Cette étape est décrite en détail en regard des figures 2, 3 et 4. Au cours d'une étape 120, on sélectionne des jeux de contraintes pour produire le document XML. Pour chaque règle de dérivation sélectionnée lors de l'étape 110 et comprenant des jeux de contraintes associés, l'un des jeux est sélectionné. Cette étape est décrite en détail en regard des figures 3 et 4. Au cours d'une étape 130, on génère l'expression XPath. Cette étape est décrite en détail en regard des figure 3 et 4, en association avec l'étape 110. Puis, au cours d'une étape 140, on génère le document XML, comme exposé en regard de la figure 5. Cette génération est réalisée en deux temps. Dans un premier temps, toutes les contraintes des jeux de contraintes sélectionnées au cours de l'étape 120 sont appliquées successivement et génèrent un squelette de document XML. Dans un deuxième temps, ce squelette est complété de manière pseudo-aléatoire. Dans la pratique, les étapes 110, 120 et 130 sont réalisées simultanément : lors de la sélection d'une règle de dérivation, cette règle de dérivation est appliquée pour participer à la génération de l'expression XPath et d'autre part, si cette règle comporte des jeux de contraintes associés, l'un de ces jeux est sélectionné. L'étape 140 peut être réalisée soit simultanément à ces trois étapes, auquel cas chaque jeu de contraintes est appliqué sur le squelette de document XML dès sa sélection, soit séparément, auquel cas, les jeux de contraintes sont mémorisés lors de leur sélection et appliqués sur le squelette du document XML après la fin de la génération de l'expression XPath. La Figure 2 présente l'algorithme initial de sélection des règles de dérivation, de sélection des jeux de contraintes et de génération de l'expression XPath. Au cours d'une étape 200, on obtient un symbole initial à dériver. Ce symbole peut être le premier symbole de la grammaire utilisée. Dans l'exemple de grammaire en annexe, il s'agit du symbole � LocationPath �. Ce symbole peut aussi être précisé par un autre moyen. Par exemple, ce symbole initial peut être défini dans des métadonnées associées à la grammaire. Une manière simple de définir ces métadonnées est de les inclure dans les commentaires de la grammaire, ou sous une syntaxe spéciale de la grammaire. Ainsi, il est possible d'ajouter par exemple la ligne suivante dans la grammaire en annexe pour préciser que le symbole initial est � AbsoluteLocationPath � : #@mainrule = AbsoluteLocationPath Puis, au cours d'une étape 210, on dérive le symbole initial. Cette étape est réalisée en mettant en oeuvre les étapes décrites en regard de la figure 3. La Figure 3 présente un l'algorithme principal de dérivation d'un symbole de la grammaire. Cet algorithme génère un ensemble d'expressions, ou de sous-expressions, XPath à partir de ce symbole. Les étapes illustrées en figure 3 génèrent aussi, pour chaque expression XPath, un arbre de jeux de contraintes associé permettant la création d'un document XML pertinent pour cette expression XPath. La Figure 3 correspond à l'algorithme de dérivation d'une occurrence du symbole S de la grammaire au sein de l'expression XPath. Cet algorithme est appelé de façon récursive, par l'intermédiaire de l'algorithme illustré en figure 4, pour réaliser la dérivation complète du symbole initial. Lors de l'appel de l'algorithme illustré en figure 3, au cours d'une étape 300, on obtient le symbole S à dériver, qui est passé en paramètre, et une liste des expressions XPath générées par cet algorithme est initialisée à la liste vide. Au cours d'une étape 305, on obtient l'ensemble des règles de dérivation correspondant au symbole S. Dans la grammaire donnée plus loin, chaque règle de dérivation est exprimée sous la forme � symbole = liste �. Ainsi cette grammaire comprend une règle de dérivation pour le symbole � AbsoluteLocationPath � : AbsoluteLocationPath = ("I", "@RelativeLocationPath") Les autres règles de dérivation pour ce symbole sont ignorées car 30 placées en commentaire. Cette grammaire comprend aussi deux règles de dérivation pour le symbole � RelativeLocationPath � : RelativeLocationPath = ("@Step") RelativeLocationPath = ("@RelativeLocationPath", "/", "@Step") Au cours d'une étape 310, on sélectionne la première règle de dérivation, R, pour le symbole S. Puis, au cours d'une étape 315, on obtient tous les jeux de contraintes associés à cette règle de dérivation R. Ensuite, au cours d'une étape 320, on sélectionne le premier jeu de contraintes, EC. Si aucun jeu de contraintes n'est associé à la règle de dérivation R, le jeu sélectionné est un jeu vide. Par exemple, la première règle de dérivation pour le symbole �AxisName � est : AxisName = ("child") Cette règle de dérivation a deux jeux de contraintes associés : depth >= 0, path = c depth >= 0, path = c ; en Le premier jeu de contraintes, contient une première contrainte "depth >= 0" portant sur la profondeur du noeud XML courant, qui doit être supérieure ou égale à 0, et une deuxième contrainte � path = c � indiquant que le nouveau noeud XML courant devient le premier fils direct du noeud XML courant. Puis, au cours d'une étape 325, on détermine si la règle de dérivation R contient des symboles non-terminaux. Par exemple, la règle de dérivation pour le symbole � AbsoluteLocationPath � contient un symbole terminal, � "/" � et un symbole non-terminal � "@RelativeLocationPath" �. Toujours en exemple le symbole � AxisName � possède deux règles de dérivation dans la grammaire en annexe : AxisName = ("child") AxisName = ("descendant") Pour la première de ces règles, la règle de dérivation ne contient qu'un seul symbole terminal, � "child" �. Un symbole non-terminal correspond à un symbole devant être dérivé, tandis qu'un symbole terminal correspond à une partie de l'expression XPath finale et n'a pas à être dérivé. Les symboles terminaux sont représentés par des chaînes de caractère entre guillemets (� " �), tandis qu'un symbole non-terminal est représenté entre guillemets par son nom précédé d'un arobase (� @ �). Ainsi, dans l'exemple de la règle de dérivation correspondant au symbole � AbsoluteLocationPath �, la valeur de la règle est � "/" "@RelativeLocationPath" �. Dans cette valeur, � "/" � est un symbole terminal, qui n'est pas dérivé. En revanche, � "@RelativeLocationPath" � est un symbole non-terminal qui doit être dérivé. Si la règle de dérivation R ne contient aucun symbole non-terminal, au cours d'une étape 330, une expression XPath correspondant au symbole S est générée. Cette expression XPath est la concaténation de l'ensemble des symboles (tous terminaux) contenus dans la règle de dérivation. Ainsi, dans l'exemple de la première règle de dérivation pour le symbole � AxisName �, l'expression XPath générée est : � child �. D'autre part, le jeu de contraintes EC est associé à cette expression XPath. En outre, une liste de variables est associée à cette expression XPath. Cette liste comporte une seule définition de variable, portant le nom du symbole S dérivé et ayant pour valeur l'expression XPath. L'expression XPath ainsi générée est ajoutée à la liste des expressions générées par cet algorithme. On passe ensuite à une étape 345. Si la règle de dérivation R contient au moins un symbole non-terminal, on passe à une étape 335, au cours de laquelle le contenu de la règle de dérivation R est dérivé. Ceci est réalisé par l'appel de l'algorithme de la figure 4, pour le contenu de cette règle de dérivation R et pour le premier symbole non-terminal de cette règle de dérivation R. Les étapes illustrées en figure 4 retournent un ensemble d'expressions XPath correspondant au contenu de la règle de dérivation R, chaque expression XPath étant associée à une liste de jeux de contraintes, et à une liste de définitions de variables. Chaque définition de variable est constituée par le nom de la variable et sa valeur. A la suite de l'étape 335, au cours d'une étape 340, on met à jour les expressions XPath retournées par l'étape 470 de la figure 4. Cette mise à jour consiste, pour chaque expression XPath, à ajouter, à la fin de sa liste de jeux de contraintes, le jeu de contraintes EC. Pour cela, l'algorithme considère, tour à tour, chaque expression XPath de la liste retournée par l'étape 470 de la figure 4. Pour chaque expression XPath XP, on modifie sa liste de jeux de contraintes. Dans ce but, on crée une copie ECC du jeu de contraintes EC. Puis, on utilise les définitions de variables associées à l'expression XP pour mettre à jour les contraintes constituant la copie du jeu de contraintes ECC. Pour chaque contrainte de la copie du jeu de contraintes ECC, si cette contrainte contient un nom de variable dans sa valeur, ce nom de variable est remplacé par la valeur de cette variable en utilisant la liste de définitions de variables obtenu au cours de l'étape 470. Ensuite, le jeu de contraintes ECC est ajouté à la fin de la liste de jeux de contraintes associé à l'expression XP. La grammaire en annexe contient un exemple de règle de dérivation dont la contrainte contient une variable. Il s'agit de l'une des règles associées au symbole � NameTest � : NameTest = ("@QName") name = @QName Le jeu de contraintes de cette règle est constitué par une contrainte de définition du nom du noeud courant. La valeur du nom du noeud courant est exprimée comme � @QName �, ce qui signifie que cette valeur prend la valeur du symbole � QName � après sa dérivation dans l'expression XPath. Ainsi, le nom cherché par l'expression XPath et le nom généré dans le document XML seront identiques. En outre, la liste de variables est associée à chaque expression XPath est modifiée en y ajoutant une nouvelle définition de variable, dont le nom est celui du symbole S dérivé et dont la valeur est l'expression XPath. Il est à noter que si la liste de définition de variables contient deux définitions différentes pour la même variable, la première définition est choisie. Dans une variante, le choix de la définition est réalisé de manière aléatoire. Dans une autre variante, l'expression XPath est dupliquée pour chacune des définitions d'une même variable, permettant d'obtenir tous les cas de figures. L'ensemble des expressions XPath associées à leur liste de jeux de contraintes et à leur liste de définitions de variables est alors ajouté à la liste des expressions générées. Dans les deux cas, il est à noter un cas particulier dans la gestion de la liste de jeux de contraintes associée aux expressions XPath. En effet, si la règle de dérivation R est indiquée comme indépendante, cette indication est portée sur chacune des listes de jeux de contraintes associées aux expressions XPath générées à partir de cette règle, à l'une des étapes 330 ou 340. La grammaire en annexe comporte un exemple de règle de dérivation indiquée comme indépendante. Il s'agit de la règle en commentaire associée au symbole � Predicate � : Predicate = Cr, "@PredicateExpr", ") @independant Cette règle comporte, dans sa liste de jeux de contraintes, la pseudo- contrainte � @independant � qui indique que cette règle de dérivation est indépendante. L'indication d'indépendance d'une liste de jeux de contraintes est utilisée lors de la génération du document XML à partir des jeux de contraintes. Dans la pratique l'indication d'indépendance d'une liste de jeux de contraintes consiste à ajouter une indication de début de liste indépendante sur le premier jeu de contraintes de la liste et une indication de fin de liste indépendante sur le dernier jeu de contraintes de la liste. Il est à noter qu'un même jeu de contraintes peut comporter plusieurs indications de début et/ou de fin de liste indépendante. A la suite de l'une des étapes 330 ou 340, au cours de l'étape 345, on détermine s'il reste d'autres jeux de contraintes associés à la règle de dérivation R non encore traités. Si c'est le cas, on sélectionne le jeu de contraintes EC suivant au cours d'une étape 350 et on retourne à l'étape 325. Si ce n'est pas le cas, on détermine, au cours d'une étape 355, s'il reste d'autres règles de dérivation non encore traitées pour le symbole S. Si c'est le cas, on sélectionne la règle de dérivation R suivante au cours d'une étape 360 et on retourne à l'étape 315. Si ce n'est pas le cas, le traitement s'achève au cours d'une étape 365, durant laquelle on retourne la liste des expressions XPath générées, ainsi que la liste de jeux de contraintes et celle des définitions de variables associées à chacune de ces expressions XPath. La figure 4 décrit un algorithme permettant de dériver l'ensemble des symboles non-terminaux contenus dans une règle de dérivation. Cet algorithme traite de manière récursive cet ensemble de symboles. Il est appelé initialement par l'algorithme de la figure 3 pour dériver le premier symbole non-terminal d'une règle de dérivation R. Il s'appelle ensuite récursivement pour dériver les autres symboles non-terminaux de la règle de dérivation R. Lors de l'appel de cet algorithme, au cours d'une étape 400, sont passés en paramètres la règle de dérivation R et l'indice du symbole S à dériver. Puis, au cours d'une étape 410, on obtient le symbole S correspondant à cet indice. Au cours d'une étape 420, ce symbole S est dérivé en appelant l'algorithme illustré en la Figure 3. En retour, on reçoit une liste d'expressions XPath correspondant aux dérivations de ce symbole S avec, pour chaque expression XPath, une liste de jeux de contraintes associée et une liste de définitions de variables associées. Puis au cours d'une étape 430, on détermine s'il reste un autre symbole non-terminal non traité dans la règle de dérivation R. Si ce n'est pas le cas, au cours d'une étape 440, on génère les résultats correspondant à la dérivation du symbole S pour la règle de dérivation R. Pour cela, on utilise la liste des expressions XPath obtenue à l'étape 420. Chacune de ces expressions XPath est modifiée en lui concaténant tous les symboles terminaux suivant le symbole S dans la règle de dérivation. Enfin, à chaque expression XPath reste associée sa liste de jeux de contraintes et sa liste de définitions de variables. L'algorithme se termine ensuite au cours d'une étape 470, durant laquelle la liste d'expressions XPath, avec les listes de variables et de jeux de contraintes associées sont retournées. Dans le cas où, au cours de l'étape 430, on détermine qu'il reste un symbole non-terminal à traiter, on effectue un appel récursif à l'algorithme illustré en figure 4, au cours d'une étape 450. Les paramètres de cet appel récursif sont la règle de dérivation R l'indice du premier symbole non-terminal suivant S. Puis, au cours de l'étape 460, on combine les dérivations réalisées à l'étape 420 et à l'étape 450. Pour cela, on crée, pour chaque combinaison d'expression XPath XP1 générée à l'étape 420 et d'expression XPath XP2 générée à l'étape 450, une nouvelle expression XPath. Cette expression XPath est la concaténation de l'expression XPath XP1, de l'ensemble des symboles terminaux suivant le symbole S dans la règle de dérivation R et précédant le symbole non-terminal suivant, dérivé lors de l'étape 450, et de l'expression XPath XP2. Dans le cas où le symbole S est le premier symbole non-terminal de la règle de dérivation R, l'ensemble des symboles terminaux précédant ce symbole S dans la règle est ajouté au début de cette nouvelle expression XPath. A cette nouvelle expression XPath est associée une liste de jeux de contraintes constituée de la concaténation de la liste de jeux de contraintes associée à XP1 et de celle associée à XP2. Il est à noter que, lors de cette concaténation, d'éventuelles indications d'indépendance sont conservées. Ces indications d'indépendances appliquées à la nouvelle liste de jeux de contraintes s'appliquent donc sur des sous-listes de cette liste. Enfin, l'ensemble de variables associé à cette nouvelle expression XPath est constitué par la combinaison des ensembles de variables associés à chacune des expressions XPath XP1 et XP2. Si une variable est définie plusieurs fois, sa définition est choisie comme décrit précédemment. Puis, on passe à l'étape 470. Il est à noter que se pose un problème de limitation des appels récursifs entre les étapes des figures 3 et 4. En effet, si une règle de dérivation comporte dans sa valeur une référence au symbole qu'elle définit, alors un nombre infini d'expressions peut être généré. Ainsi, par exemple, la deuxième règle de dérivation pour le symbole � RelativeLocationPath � dans la grammaire en annexe fait référence à ce même symbole : RelativeLocationPath = ("@RelativeLocationPath", "/", "@Step") Un tel problème peut aussi surgir à cause de cycles de références entre plusieurs règles de dérivation. Pour prévenir ce problème, on limite le nombre d'appels récursifs entre les étapes illustrées dans les figures 3 et 4. Une première solution consiste à compter le nombre d'appels récursifs à l'algorithme de la Figure 3. Quand ce nombre d'appels récursifs atteint une valeur limite, l'algorithme de la Figure 3 retourne une expression XPath d'erreur d'appel récursif, au lieu de dériver effectivement le symbole qui lui est transmis. Par la suite, toutes les expressions XPath générées contenant cette expression XPath d'erreur de récursion seront éliminées de la liste des expressions XPath générées. Cependant, cette première solution n'est pas préférentielle car elle permet d'explorer beaucoup de possibilités d'appels récursifs pour les premières règles de dérivation rencontrées, mais ne le permet pas pour les règles rencontrées après plusieurs dérivations. Une deuxième solution, préférentielle, consiste à compter le nombre d'appels récursifs à l'algorithme de la Figure 3 concernant uniquement un symbole déjà dérivé au moins une fois par ce même algorithme. Cette solution permet d'explorer facilement l'ensemble de l'arbre des règles de dérivation tout en évitant des appels récursifs en trop grand nombre. Comme pour la première solution, quand le nombre d'appels compté atteint une valeur limite prédéfinie, l'algorithme de la figure 3 retourne une expression XPath d'erreur d'appel récursif. Dans la pratique, selon les grammaires une valeur limite variant entre deux et quatre produit de bons résultats. La Figure 5 décrit la génération d'un document XML à partir d'une liste de jeux de contraintes. Cet algorithme est conçu pour être appelé sur l'une des listes de jeux de contraintes créées par l'algorithme décrit à la Figure 3. Au départ, le document XML est constitué par son noeud racine. En outre, une liste de noeuds courants est initialisée comme contenant un unique élément qui est ce noeud racine. Au cours d'une étape 500, on sélectionne le premier jeu de contraintes de la liste, EC. Ensuite, au cours d'une étape 510, on détermine si le jeu de contraintes EC considéré est le premier d'une sous-liste indépendante de jeux de contraintes. Si c'est le cas, une copie de la liste de noeuds courants est mémorisée. Puis, au cours d'une étape 520, on applique les contraintes de test contenues dans la liste EC, en faisant appel aux étapes décrites en regard de la figure 6. Au cours d'une étape 530, on applique les contraintes de génération de la liste EC, ce qui est réalisé par un appel aux étapes décrites en regard de la figure 7. Une contrainte de test correspond à une vérification à réaliser sur la liste de noeuds courants. Elle est utilisée pour filtrer la liste de noeuds courants. Une contrainte de test peut porter par exemple sur la profondeur du noeud courant, sur son nom, sur son type. Une contrainte de génération permet de compléter le document XML. Une contrainte de génération peut soit préciser la définition d'un noeud déjà existant, soit créer un nouveau noeud. Puis, au cours d'une étape 540, on détermine si le jeu de contraintes EC considéré est le dernier d'une sous-liste indépendante de jeux de contraintes. Si oui, la liste de noeuds courants prend pour valeur la valeur mémorisée au début de cette sous-liste indépendante au cours de l'étape 510. La gestion de la mémorisation des listes de noeuds courants au début et fin de sous-liste indépendante peut être réalisée par exemple à l'aide d'une pile. Puis, au cours d'une étape 550, on détermine s'il reste au moins un jeu de contraintes dans la liste. Si oui, au cours d'une étape 560, on obtient le jeu de contraintes suivant, EC, dans la liste. Puis on retourne à l'étape 510 pour traiter ce nouveau jeu de contraintes EC. Sinon, au cours d'une étape 570, le document XML est complété : tous les noeuds du document XML (éléments, attributs...) qui ne sont pas entièrement définis voient leurs caractéristiques définies de manière pseudo-aléatoire. Cela est réalisé lors d'un parcours de l'arbre représentant le document XML. Pour chaque caractéristique non-définie, la valeur pseudo-aléatoire utilisée est un préfixe dépendant de la caractéristique, suivi d'un numéro d'ordre. Ainsi, un élément n'ayant pas de nom pourra être nommé � elem-35 � par exemple, tandis qu'un attribut dont la valeur n'est pas définie prendra pour valeur � val-421 �. D'autres types de remplissages pseudo-aléatoires peuvent être envisagés. En particulier le numéro d'ordre peut être omis. Une autre possibilité est de définir le préfixe et l'utilisation du numéro d'ordre dans le fichier de définition de la grammaire. L'étape 570 se termine alors en retournant le document XML généré. Lors de la génération du document XML, si une contrainte ne peut être appliquée, alors la génération de ce document XML est arrêtée et l'expression XPath correspondante est retirée de la liste des expressions XPath générées. Cela peut se produire, par exemple, si une contrainte tente d'accéder au fils d'un attribut (on rappelle qu'un attribut ne peut avoir de fils). Cela peut aussi se produire si une contrainte tente de redéfinir le nom d'un élément avec une nouvelle valeur. D'autres comportements peuvent être envisagés. Ainsi si une contrainte de génération ne peut être appliquée, elle peut être simplement ignorée. Une autre variante consiste à indiquer, dans la définition de la grammaire, si une contrainte de génération est impérative ou non. Si elle est impérative, l'échec de son application provoque l'arrêt de la génération. Sinon, l'échec de son application conduit simplement à ignorer cette contrainte. Par ailleurs, la définition de l'échec ou non de l'application d'une contrainte dépend de la contrainte et peut varier. Ainsi la redéfinition de la valeur d'une caractéristique d'un noeud peut être considérée ou non comme un échec. Ce choix peut être réalisé de manière globale, ou peut être précisé dans la grammaire pour chaque contrainte. La Figure 6 décrit un algorithme permettant d'appliquer des contraintes de test pour la génération d'un document XML. Les contraintes de test permettent de filtrer la liste des noeuds courants avant l'application des contraintes de génération de cette même liste, comme exposé en regard de la figure 7. L'algorithme de la figure 6 est appelé au cours d'une étape 600, avec, en paramètre, un jeu de contraintes. Puis, au cours d'une étape 610, on obtient la liste des noeuds courants L. Ensuite, au cours d'une étape 620, on obtient une première contrainte C de la liste des contraintes. Au cours d'une étape 630, on détermine si cette contrainte C est une contrainte de test. Si oui, au cours d'une étape 640, on applique la contrainte de test C à la liste des noeuds courants L. A cet effet, on applique la contrainte de test C à chacun des noeuds courants de la liste L. Si la contrainte de test C retourne un résultat positif pour un noeud courant de la liste L, ce noeud est conservé dans la liste L. Sinon, le noeud est supprimé de la liste. Ainsi, la contrainte de test C réalise une opération de filtre sur la liste de noeuds courants L. Si le résultat de l'étape 630 est négatif ou à la suite de l'étape 640, au cours d'une étape 650, on détermine s'il reste d'autres contraintes non traitées dans le jeu de contraintes obtenu en paramètre au cours de l'étape 600. Si oui, au cours d'une étape 660, on obtient la contrainte suivante C et on retourne à l'étape 630. Sinon, au cours d'une étape 670, la liste des noeuds courants a été mise à jour et l'algorithme se termine. La Figure 7 décrit un algorithme permettant d'appliquer des contraintes de génération pour la génération d'un document XML. Les contraintes de génération permettent de définir des noeuds dans le document XML. Au cours d'une étape 700, cet algorithme est appelé avec, en paramètre, un jeu de contraintes. Puis, au cours d'une étape 710, on obtient la liste des noeuds courants L. Au cours d'une étape 720, on obtient une première contrainte C de la liste des contraintes. Au cours d'une étape 730, on détermine si cette contrainte C est une contrainte de génération. Si oui, au cours d'une étape 740, on applique la contrainte de génération C à la liste de noeuds courants L. A cet effet, on applique la contrainte de génération C à chacun des noeuds courants de la liste L. Cette contrainte de génération C réalise ainsi son action de génération sur chacun des noeuds de la liste L. En outre, chaque application de la contrainte de génération C à un noeud peut retourner une liste de noeuds. Tous les noeuds composant ces listes retournées sont réunis pour former une nouvelle liste de noeuds courants. Si le résultat de l'étape 730 est négatif ou à la suite de l'étape 740, au cours d'une étape 750, on détermine s'il reste d'autres contraintes non traitées dans le jeu de contraintes obtenu, en paramètre, au cours de l'étape 700. Si oui, au cours d'une étape 760, on obtient la contrainte suivante C et on retourne à l'étape 730. Sinon, au cours d'une étape 770, la liste des noeuds courants est mise à jour et l'algorithme se termine. On note ici que différents types de contraintes peuvent être utilisés. La contrainte de profondeur est une contrainte de test qui permet de vérifier la profondeur d'un noeud courant au sein de l'arbre XML. Elle permet en particulier d'éviter de tenter d'accéder au parent d'un noeud qui n'en a pas. La grammaire en annexe contient plusieurs exemples de contraintes de profondeur. Ainsi la règle de dérivation suivante en contient : AxisName = ("child") depth >= 0, path = c depth >= 0, path = c; en Chacun des deux jeux de contraintes contient une contrainte � depth >= 0 � qui vérifie que la profondeur du noeud courant est supérieur ou égale à 0. La contrainte de chemin est une contrainte de génération qui permet de naviguer dans le document XML. Une contrainte de chemin crée tous les noeuds qu'elle traverse. Une contrainte de chemin est définie par un ou plusieurs chemins. La contrainte de chemin retourne le noeud final atteint par chacun de ses chemins. Chaque chemin contient une liste d'actions. Les actions possibles peuvent être : - � c � : aller au premier enfant du noeud courant ; - � p � : aller au parent du noeud courant ; - � n � : aller au frère suivant du noeud courant ; - � p � : aller au frère précédent du noeud courant ; - � r � : aller à la racine et - � a � : aller au premier attribut du noeud courant. En outre, l'action particulière � i � signifie que le noeud final atteint par le chemin ne doit pas être retourné. Ainsi, dans le premier jeu de contraintes de la règle de dérivation précédente, la contrainte de chemin � path = c � contient un seul chemin qui spécifie d'aller au premier noeud fils d'un noeud courant. Ce noeud est donc créé s'il n'existe pas et fait partie de la nouvelle liste de noeuds courants. Pour le deuxième jeu de contraintes, la contrainte de chemin � path = c ; cn � contient deux chemins. Le premier, � c �, spécifie d'aller au premier fils d'un noeud courant. Le deuxième, � cn �, spécifie d'aller au deuxième fils d'un noeud courant (le frère suivant du premier fils du noeud courant). Ainsi, l'application de cette contrainte sur un noeud provoque la création de ses deux premiers fils (sauf s'ils existent déjà). En outre, ces deux noeuds créés font partie de la nouvelle liste des noeuds courants. Il est à noter que la liste des actions pour les contraintes de chemin peut être aisément étendue, par exemple pour accéder directement à un petit enfant du noeud courant. La contrainte de nom est soit une contrainte de test, soit une contrainte de génération. Dans le cas où elle est une contrainte de test, elle vérifie que le nom du noeud courant est bien égal à la valeur de la contrainte. Dans le cas où elle est une contrainte de génération, elle permet de définir le nom du noeud courant. Ce nom correspond au nom qualifié d'un élément ou d'un attribut, au contenu d'un commentaire, d'un texte ou d'une instruction de traitement. Une contrainte de nom conserve les noeuds qu'elle traite comme noeuds courants. Ainsi, la règle de dérivation suivante contient une contrainte de nom (en tant que contrainte de génération) : NameTest = ("@QName") name = @QName Cette contrainte de nom définit la valeur du nom du noeud courant comme étant la valeur de la sous-expression XPath dérivée à partir du symbole � QName �. Ainsi, le même nom qualifié sera utilisé dans l'expression XPath et dans le document XML, ce qui permet à l'expression XPath d'avoir un résultat dans le document XML (en supposant que le reste de l'expression concorde avec le reste du document XML). De manière similaire, la contrainte de valeur est soit une contrainte de test, soit une contrainte de génération. Cette contrainte ne s'applique qu'aux attributs du document XML. Dans le cas où elle est une contrainte de test, elle vérifie que la valeur du noeud courant est bien égale à la valeur de la contrainte. Dans le cas où elle est une contrainte de génération, elle permet de définir la valeur du noeud courant. Une contrainte de valeur conserve les noeuds qu'elle traite comme noeuds courants. La contrainte de type est soit une contrainte de test, soit une contrainte de génération. Dans le cas où elle est une contrainte de test, elle vérifie que le type du noeud courant (élément, attribut, texte...) est bien égal à la valeur de la contrainte. Dans le cas où elle est une contrainte de génération, elle permet de définir le type du noeud courant. Une contrainte de type conserve les noeuds qu'elle traite comme noeuds courants. Une contrainte d'espace de nommage est soit une contrainte de test, soit une contrainte de génération. Dans le cas où elle est une contrainte de test, elle permet soit de vérifier que l'espace de nommage du noeud courant est bien égal à la valeur de la contrainte, soit de vérifier que le préfixe et l'espace de nommage décrits dans la valeur de la contrainte sont bien associés au niveau du noeud courant. Dans le cas où elle est une contrainte de génération, elle permet d'associer un préfixe à un espace de nommage pour le noeud courant (uniquement pour les éléments). Cette association peut s'appliquer au document XML, mais aussi au contexte d'évaluation de l'expression XPath. La définition de la contrainte précise à quoi elle s'applique (par défaut, elle s'applique aux deux). Une contrainte d'espace de nommage conserve les noeuds qu'elle traite comme noeuds courants. Ainsi, la règle de dérivation suivante contient une contrainte d'espace de nommage : Prefix = ("nsl ") xmins = nsl:http://www.crf.canon. fr/namespacel Tandis que la dérivation produit un préfixe � nsl � au niveau de l'expression XPath, la contrainte � xmins nsl:http://www.crf.canon.fr/namespacel � associe ce préfixe à l'espace de nommage � http://www.crf.canon.fr/namespacel � au niveau du noeud courant, et aussi au niveau du contexte d'évaluation de l'expression XPath. La contrainte de variable est une contrainte de génération spécifique. Elle ne modifie par le document XML, mais crée une nouvelle définition de variable au niveau du contexte d'évaluation de l'expression XPath. Ainsi lors de l'évaluation de l'expression XPath, si cette expression contient une référence à cette variable, cette référence pourra être remplacée par sa valeur telle que définie. Une contrainte de définition de variable conserve les noeuds qu'elle traite comme noeuds courants. Ainsi, la règle de dérivation suivante (non présente dans la grammaire en annexe) contient une contrainte de variable : VariableReference = ("$myvar") var = myvar=5 Cette contrainte permet de définir la variable � myvar � comme ayant la valeur � 5 � au niveau du contexte d'évaluation de l'expression XPath. On observe que le mode de réalisation particulier du procédé objet de la présente invention, tel que décrit en regard des figures, peut aisément être étendu pour générer des expressions XPath multiples relatives à un même document XML. Pour cela, il suffit de combiner plusieurs expressions XPath en une liste d'expressions, et de ne générer qu'un seul document XML à partir de toutes les listes de jeux de contraintes associées à toutes les expressions XPath regroupées. Cependant, ces jeux de contraintes peuvent ne pas être compatibles. Plusieurs solutions peuvent être envisagées pour résoudre ce problème. Tout d'abord, comme décrit précédemment, les règles d'incompatibilité des contraintes peuvent être rendue flexibles, en ignorant par exemple les contraintes ne pouvant être appliquées. Cependant celle solution permet d'arriver à générer un document XML, mais ce document XML risque d'être peu pertinent par rapport aux expressions XPath pour lesquelles des contraintes ont été ignorées. D'autre part, il est intéressant d'utiliser au mieux les filtres. Ainsi il est possible d'ajouter une nouvelle contrainte pour sélectionner facilement un ensemble de noeuds (les enfants du noeud courant, ses voisins), puis d'utiliser une contrainte de nom ou de type pour réduire cette sélection avant de mettre en oeuvre les contraintes utilisée lors de la génération d'expression XPath indépendantes. Une autre solution est d'étendre les contraintes de chemin pour autoriser plus de possibilités. Ainsi il est possible de définir de nouvelles actions comme � C � qui signifie de créer un nouvel enfant pour le noeud courant à la première position disponible, ou � A � qui agit de même pour les attributs. Une autre solution est de modifier l'algorithme d'application d'un jeu de contraintes. Lors de l'application d'une contrainte de chemin comme � c � ou � a �, le premier noeud enfant ou le premier attribut du noeud courant est sélectionné. Puis les contraintes suivantes sont appliquées. Si l'application d'une contrainte n'est pas possible, alors l'algorithme revient en arrière et sélectionne le noeud enfant suivant ou l'attribut suivant. Cette solution, même si elle permet un meilleur mélange des contraintes liées aux différentes expressions XPath a cependant l'inconvénient d'être complexe à mettre en oeuvre. Dans tous les cas, il est aussi possible de créer plusieurs documents XML pour une liste d'expressions en appliquant les listes de jeux de contraintes 20 associées dans des ordres différents. Une variante consiste à appliquer les listes de jeux de contraintes de manière mélangée : au lieu d'appliquer une première liste, puis une deuxième et ainsi de suite, le premier ensemble de la première liste est appliqué, puis le premier de la deuxième et ainsi de suite. Il convient cependant de conserver un 25 jeu de noeuds courants pour chaque liste. Cette variante permet de mélanger l'action des listes de contraintes au sein du document XML. L'invention décrite ici s'adapte aisément à d'autres langages. En effet, elle permet de générer des jeux de tests pour tout langage de requête portant sur un document structuré. Ainsi, pour des documents structurés 30 utilisant le langage XML, le langage de requête peut être XPath, qui sert d'exemple dans la description de l'invention, mais aussi XQuery, ou même XSLT. Le langage XSLT permet de transformer un document XML en un autre document (XML ou non). Pour cela, une transformation XSLT comprend des expressions XPath qui permettent de sélectionner des parties du document XML et des commandes XSLT qui permettent de modifier les parties sélectionnées et de les utiliser dans la génération du document de sortie. Dans le cas du langage XSLT, la génération est en partie similaire à celle utilisée pour les expressions multiples. La différence est que la grammaire utilisée mélange le langage XSLT et le langage XPath. Lors de la génération des expressions, chaque expression générée est une transformation XSLT. A chaque transformation XSLT est associée une liste de jeu de contraintes. Mais cette liste provient en réalité de la concaténation de l'ensemble des listes générées pour les expressions XPath contenues dans la transformation XSLT. Aussi, il est nécessaire de mettre en oeuvre les techniques indiquées dans le cas des expressions multiples pour résoudre les problèmes de compatibilité entre les contraintes et pour pouvoir générer un document XML pertinent vis-à-vis de la transformation XSLT et donc de l'ensemble de ses expressions XPath. On donne, en annexe, un exemple de grammaire utilisé pour générer des jeux de tests pour le langage XPath et des documents XML. Cette grammaire est spécialisée pour tester l'axe � descendant � du langage XPath. Par conséquent, cette grammaire ne reprend qu'une partie des règles de grammaire décrivant la syntaxe du langage XPath. Les lignes commençant par le caractère `#' correspondent à des lignes de commentaire. Les lignes vides sont ignorées. Les autres lignes sont soit des règles de dérivation de la grammaire, soit des définitions de contraintes. Les règles de dérivation de la grammaire utilisent une notation proche de la notation Backus-Naur form (BNF). La principale différence est que plusieurs choix de dérivation ne sont pas exprimés par le symbole 'I' dans la partie droite de la règle, mais sont représentées par plusieurs règles ayant la même partie gauche. Ainsi, cette grammaire définit deux dérivations possibles pour le symbole � RelativeLocationPath �. Les dérivations sont décrites par une liste de symboles placés entre parenthèses et séparés par des virgules dans la partie droite de la règle. Les symboles débutant par le caractère `@' correspondent à une référence à un symbole non-terminal défini par d'autres règles de dérivation, tandis que les autres symboles sont des symboles terminaux et correspondent à des chaînes de caractères. Les contraintes sont décrites sur des lignes commençant en retrait sous la règle de dérivation à laquelle elles correspondent. Une ligne contient un jeu de contraintes séparées par des virgules. Chaque contrainte est définie par son nom, un opérateur de comparaison ou d'affectation ('=', �='...) et une ou plusieurs valeurs séparées par des points-virgules. Une valeur commençant par le caractère '@' fait référence au symbole correspondant dans la règle à laquelle est associée la contrainte. Lors de la création du document XML, cette valeur sera remplacée par la dérivation complète réalisée pour le symbole correspondant. On observe, en figure 8, un mode particulier de réalisation du dispositif 800 de génération d'expression et de documents objet de la présente invention, et différents périphériques adaptés à implémenter chaque aspect de la présente invention. Dans le mode de réalisation illustré en figure 8, le dispositif 800 est un micro-ordinateur de type connu connecté, par le biais d'une carte d'entrée/sortie 804, à un moyen d'acquisition ou de stockage d'au moins les éléments d'une implémentation XPath à tester 801, par exemple une interface avec un réseau informatique local ou avec une mémoire, adapté à fournir des données. Le dispositif 800 comporte une interface de communication 818 reliée à un réseau 834 apte à transmettre, en entrée, des données numériques à tester et, en sortie, des expressions et documents fournis par le dispositif 800. Le dispositif 800 comporte également un moyen de stockage 812, par exemple un disque dur, et un lecteur 814 de disquette 816. La disquette 816 et le moyen de stockage 812 peuvent contenir des données à tester, des données de test et/ou des données testées et un programme informatique adapté à implémenter le procédé de génération d'expressions et de documents objet de la présente invention. Selon une variante, le programme permettant au dispositif de mettre en oeuvre la présente invention est stocké en mémoire morte ROM (acronyme de � read only memory � pour mémoire non réinscriptible) 806. Selon une autre variante, le programme est reçu par l'intermédiaire du réseau de communication 834 avant d'être stocké. Le dispositif 800 possède un écran 805 permettant de visualiser les données à tester, de test ou testées ou servant d'interface avec l'utilisateur pour paramétrer certains modes d'exécution du dispositif 800, à l'aide d'un clavier 810 et/ou d'une souris par exemple. Une unité centrale CPU (acronyme de � central processing unit �) 803 exécute les instructions du programme informatique et de programmes nécessaires à son fonctionnement, par exemple un système d'exploitation. Lors de la mise sous tension du dispositif 800, les programmes stockés dans une mémoire non volatile, par exemple la mémoire morte 806, le disque dur 812 ou la disquette 816, sont transférés dans une mémoire vive RAM (acronyme de � random access memory � pour mémoire à accès aléatoire) 808 qui contiendra alors le code exécutable du programme objet de la présente invention ainsi que des registres pour mémoriser les variables nécessaires à sa mise en oeuvre. Bien entendu, la disquette 816 peut être remplacée par tout support d'information amovible, tel que disque compact, clé ou carte mémoire. De manière plus générale, un moyen de stockage d'information, lisible par un ordinateur ou par un microprocesseur, intégré ou non au dispositif, éventuellement amovible, mémorise un programme objet de la présente invention. Un bus de communication 802 permet la communication entre les différents éléments inclus dans le dispositif 800 ou reliés à lui. La représentation, en figure 8, du bus 802 n'est pas limitative et notamment l'unité centrale 803 est susceptible de communiquer des instructions à tout élément du dispositif 800 directement ou par l'intermédiaire d'un autre élément du dispositif 800. Le dispositif décrit ici et, particulièrement, l'unité centrale 803, sont susceptibles d'implémenter tout ou partie des traitements décrits en regard des figures 1 à 7, pour mettre en oeuvre chaque procédé objet de la présente invention et constituer chaque dispositif objet de la présente invention. ANNEXE ## Test 'descendant' Axis. ## ## 2 LocationPaths ## #1 #LocationPath = ("@RelativeLocationPath") LocationPath = ("@AbsoluteLocationPath") #2 #AbsoluteLocationPath = Cr) AbsoluteLocationPath = ("l", "@RelativeLocationPath") #AbsoluteLocationPath = ("@AbbreviatedAbsoluteLocationPath") #3 RelativeLocationPath = ("@Step") RelativeLocationPath = ("@RelativeLocationPath", "1", "@Step") #RelativeLocationPath = ("@AbbreviatedRelativeLocationPath") ## ## 2.1 Location Steps ## #4 Step = ("@AxisSpecifier", "@NodeTest") #Step = ("@AxisSpecifier", "@NodeTest", "@Predicates") #Step = ("@AbbreviatedStep") #5 AxisSpecifier = ("@AxisName", "::") #AxisSpecifier = ("@AbbreviatedAxisSpecifier") ## ## 2.2 Axes ## #6 #AxisName = ("ancestor") #AxisName = ("ancestor-or-self') #AxisName = ("attribute") AxisName = ("child") depth >= 0, path = c depth >= 0, path = c; en AxisName = ("descendant") depth >= 0, path = # Negative test. depth >= 0, path = a # Negative test. depth >= 0, path = c depth >= 0, path = cc depth >= 0, path = c; cn depth >= 0, path = c; cni depth >= 0, path = ci; cn #AxisName = ("descendant-or-self') #AxisName = ("following") #AxisName = ("following-sibling") #AxisName = ("namespace") #AxisName = ("parent") #AxisName = ("preceding") #AxisName = ("preceding-sibling") #AxisName = ("self') ## ## 2.3 Node Tests ## #7 NodeTest = ("@NameTest") #NodeTest = ("@NodeType", "()") #NodeTest = ("processing-instruction(", "@Litera)", ")")30 #Predicate = Cr, "@PredicateExpr", # @independant #9 #PredicateExpr = ("@Expr") ## ## 3 Expressions ## ## ## 3.7 Lexical Structure ## #37 NameTest = ("*") name = any NameTest = ("@Prefix", ":*") name = @Prefix:any NameTest = ("@QName") name = @QName #38 NodeType = ("comment") NodeType = ("text") NodeType = ("processing-instruction") NodeType = ("node") #XML-4 - Modified for terminais NCName = ("target") #XML-7 QName = ("@PrefixedName") QName = ("@UnprefixedName") #XML-8 PrefixedName = ("@Prefix", ":", "@LocalPart") #XML-9 UnprefixedName = ("@LocalPart") ' #XML-10 - Modified for terminais Prefix = ("ns1") xmins = nsl:http://www.crf.canon.fr/namespacel #XML-11 LocalPart = ("@NCName") REVENDICATIONS 1 û Procédé de génération de jeux de test, caractérisé en ce qu'il comporte : - une étape (305) d'obtention d'un jeu de règles de grammaire décrivant un premier langage, - une étape (315) d'obtention d'au moins un jeu de contraintes liées aux dites règles de grammaire décrivant le premier langage, - une étape (330) de génération d'au moins une expression dans le premier langage, en mettant en oeuvre lesdites règles de grammaire décrivant le premier langage et - une étape (140) de génération d'un document dans un deuxième langage, en appliquant ledit au moins un jeu de contraintes audit document. 2 - Procédé selon la revendication 1, caractérisé en ce qu'il comporte, avant l'étape d'obtention d'au moins un jeu de contraintes, une étape de sélection d'un ensemble de règles de grammaire du premier langage dites � de dérivation �, et en ce que les règles de dérivation sont utilisées au cours de l'étape d'obtention d'au moins un jeu de contraintes et au cours de l'étape de la génération d'au moins une expression dans le premier langage. 3 û Procédé selon l'une quelconque des revendications 1 ou 2, caractérisé en ce que, au cours de l'étape de génération d'un document, chaque partie du document qui n'est pas complètement définie par lesdites contraintes, est complétée de manière aléatoire. 4 û Procédé selon l'une quelconque des revendications 1 à 3, caractérisé en ce 25 que, au cours de l'étape de génération d'au moins une expression, au moins une dite expression est une expression XPath. 5 û Procédé selon l'une quelconque des revendications 1 à 4, caractérisé en ce que, au cours de l'étape de génération de documents, on génère des documents XML. 30 6 û Procédé selon l'une quelconque des revendications 1 à 5, caractérisé en ce que, au cours de l'étape de génération d'au moins une expression, lagrammaire est réduite et ne comprend qu'une partie de la définition du premier langage. 7 ù Procédé selon l'une quelconque des revendications 1 à 6, caractérisé en ce que, au cours de l'étape de génération d'au moins une expression, la syntaxe du premier langage est définie à partir de symboles, chaque symbole étant défini à partir d'un ensemble de règles de grammaire dites � de dérivation � qui expriment l'ensemble des possibilités autorisées par le premier langage pour ce symbole à partir d'autres symboles et de chaînes de caractères. 8 ù Procédé selon la revendication 7, caractérisé en ce qu'au moins un jeu de 10 contraintes est associé à une règle de dérivation. 9 ù Procédé selon la revendication 8, caractérisé en ce que, au cours de l'étape de génération d'au moins une expression dans le premier langage, on sélectionne un ensemble de règles de dérivation de ladite grammaire pour produire une expression dans le premier langage, en sélectionnant un symbole 15 initial, puis en réalisant des dérivations jusqu'à ce que l'expression ne contienne plus aucun symbole pouvant être dérivé. ù Procédé selon l'une quelconque des revendications 1 à 9, caractérisé en ce que les contraintes sont appliquées successivement à un ensemble de noeuds courants du document dans le deuxième langage. 20 11 ù Procédé selon la revendication 10, caractérisé en ce qu'il met en oeuvre des ensembles indépendants de jeux de contraintes, un ensemble de noeuds courants restant inchangé après application d'un ensemble indépendant de jeux de contraintes. 12 ù Procédé selon l'une quelconque des revendications 10 ou 11, caractérisé 25 en ce que ledit jeu de contraintes comporte au moins une contrainte de test. 13 ù Procédé selon la revendication 12, caractérisé en ce qu'au moins une dite contrainte de test concerne une profondeur, un nom, une valeur, un type et/ou un espace de nommage pour au moins l'un des noeuds courants. 14 ù Procédé selon l'une quelconque des revendications 10 à 13, caractérisé 30 en ce que ledit jeu de contraintes comporte au moins une contrainte de génération.15 û Procédé selon la revendication 14, caractérisé en ce qu'au moins une contrainte de génération concerne un chemin, un nom, une valeur, un type, un espace de nommage et/ou une définition de variable pour au moins l'un des noeuds courants. 16 û Procédé selon l'une quelconque des revendications 1 à 15, caractérisé en ce que, au cours de l'étape de génération d'un document dans un deuxième langage, en appliquant le jeu de contraintes audit document, un document XML est créé en appliquant successivement chaque jeu de contraintes associé à une règle de grammaire. 17 û Procédé selon la revendication 16, caractérisé en ce que ledit document XML est créé en appliquant, au sein d'au moins un jeu de contraintes comportant des contraintes de test et des contraintes de génération, d'abord les contraintes de test et, ensuite, les contraintes de génération. 18 û Dispositif de génération de jeux de test, caractérisé en ce qu'il comporte : - un moyen d'obtention d'un jeu de règles de grammaire décrivant un premier langage, - un moyen d'obtention d'un jeu de contraintes liées aux dites règles de grammaire décrivant le premier langage, - un moyen de génération d'au moins une expression dans le premier langage, en mettant en oeuvre lesdites règles de grammaire décrivant le premier langage et - un moyen de génération d'un document dans un deuxième langage, en appliquant le jeu de contraintes audit document. 19 - Programme d'ordinateur chargeable dans un système informatique, ledit 25 programme contenant des instructions permettant la mise en oeuvre du procédé selon l'une quelconque des revendications 1 à 17. 20 - Support d'informations lisibles par un ordinateur ou un microprocesseur, amovible ou non, conservant des instructions d'un programme informatique, caractérisé en ce qu'il permet la mise en oeuvre du procédé selon l'une 30 quelconque des revendications 1 à 17.