Bonjour chers lecteurs. Ce post se concentrera sur les applications légÚrement non standard d'un formalisme aussi connu que XPath. Tout le monde sait qu'il est trÚs pratique d'extraire des informations à partir de XML ou HTML ou d'autres documents * ML (à la fois du texte brut et des documents virtuels, qui sont la couche supérieure de la représentation de toute information complexe), puis il y a afin de poser ces documents des questions. Cependant, on sait que mieux la question est formulée, plus elle contient déjà une partie de la réponse. Par conséquent, une pensée simple se suggÚre: est-il possible d'utiliser des expressions écrites dans XPath comme affirmant, c'est-à -dire de construire un document pour que cette expression XPath soit vraie? Je pense que c'est possible, et c'est la premiÚre chose qui sera discutée ici. Et le second - si nous apprenons à créer directement de nouveaux éléments dans un document en utilisant directement XPath, est-il possible de transformer XPath en un langage de programmation algorithmique simple? En fait, il sait accéder aux données, il sait créer des données. Il est facile d'imaginer comment décrire la séquence d'opérateurs et l'opérateur de branche sur elle, il reste à penser aux cycles qu'elle contient et aux fonctions. C'est intéressant, du moins théoriquement. Et cela sera également discuté.
Construire XPath
Ainsi, XPath ordinaire dĂ©crit une sĂ©quence d'Ă©tapes pour se dĂ©placer dans une arborescence de documents, et une condition de filtre peut ĂȘtre imposĂ©e Ă chaque Ă©tape (un prĂ©dicat Ă©crit entre crochets). En consĂ©quence, nous obtenons un ensemble fini de nĆuds ou un nombre ou une chaĂźne ou une valeur logique. Nous nous intĂ©ressons principalement au cas des nĆuds multiples. XPath normal produit des nĆuds qui existent dĂ©jĂ dans le document. ConsidĂ©rons une hypothĂ©tique construction XPath qui non seulement renverra des nĆuds existants, mais construira Ă©galement de nouveaux nĆuds de maniĂšre Ă ce qu'ils correspondent pleinement Ă la requĂȘte.
L'idĂ©e est trĂšs simple - Ă l'Ă©tape suivante de la requĂȘte XPath, nous analyserons le prĂ©dicat de filtre et compilerons les variantes de donnĂ©es qui relĂšvent de ce filtre. Et puis nous vĂ©rifierons laquelle de ces options existe dĂ©jĂ et terminerons la construction de celles qui n'existent pas.
Par exemple, voici une requĂȘte:
/OBJS/Var[@A=1 and @B=1 or @A=2 or @A=3]/X
Si nous le considérons comme une construction, nous allons tout d'abord vérifier si l'élément racine <OBJS> existe, et sinon, le créer. Vient ensuite l'étape Var avec un filtre. Je ne décrirai pas les rÚgles selon lesquelles le filtre de prédicat est traité afin de ne pas compliquer la présentation, je dirai seulement que ce filtre décrit clairement les trois ensembles de données sur lesquels il est vrai:
- <Var A = â1â B = â1â />
- <Var A = â2â />
- <Var A = â3â />
Nous devons donc nous assurer que l'élément <OBJS> a des éléments enfants <Var> avec de telles données. Et, enfin, l'étape suivante est X sans condition - cela signifie qu'il est nécessaire que chaque élément Var ait un élément enfant <X>.
Donc, tout est simple. Ă la suite de l'application d'un tel XPath de construction, par exemple, Ă un document
<OBJS> <Var A=â2â /> </OBJS>
on obtient le document de sortie:
<OBJS> <Var A=â2â> <X/> </Var> <Var A=â1â B=â1â> <X/> </Var> <Var A=â3â> <X/> </Var> </OBJS>
Et en mĂȘme temps, nous avons gĂ©rĂ© exclusivement avec XPath, sans XSL ou quelque chose comme ça.
XPath algorithmique
Nous avons donc appris à XPath comment créer des données. Maintenant, apprenez-lui (un peu) à les traiter de façon algorithmique.
La sĂ©quence d'opĂ©rateurs peut ĂȘtre dĂ©crite par une expression ET logique habituelle. Il est calculĂ© strictement de gauche Ă droite, c'est ce dont vous avez besoin. S'il doit ĂȘtre entiĂšrement implĂ©mentĂ©, il vous suffit de vous assurer que tous ses Ă©lĂ©ments renvoient une vĂ©ritable expression.
A and B and C ⊠and Z
Un opérateur conditionnel de la forme
if (A) puis B else C , bien sĂ»r (et je ne dirai rien de nouveau ici), peut ĂȘtre dĂ©crit par une expression logique
A and B or C
Tout est un peu plus compliquĂ© avec la boucle. Je ne voulais tout simplement pas l'introduire comme ça, alors j'ai dĂ©cidĂ© de simplement introduire le concept d'une fonction XPath, qui peut ĂȘtre rĂ©cursive. Et puis tout cycle peut ĂȘtre reprĂ©sentĂ© comme une chaĂźne d'appels rĂ©cursifs avec vĂ©rification de la condition de fin.
En principe, c'est presque tout (dans la version minimale). MĂȘme les variables ne sont pas nĂ©cessaires - elles sont remplacĂ©es par des Ă©lĂ©ments du document actuel. Seuls les arguments de fonction nommĂ©s sont requis.
Je vais vous donner un exemple. Supposons que nous ayons un document contenant deux listes de nombres décrites par une série d'éléments <list> imbriqués:
<a> <b> <list data="1"><list data="2"></list></list> </b> <c> <list data="3"><list data="4"></list></list></c> </a>
Soit qu'il soit nĂ©cessaire de concatĂ©ner des listes de l'Ă©lĂ©ment <b> et de l'Ă©lĂ©ment <c> et de placer le rĂ©sultat directement dans <a>. Pour ce faire, trois fonctions XPath doivent ĂȘtre introduites:
concat_list($#, $##): add_list(#/self::*) and add_list(##/self::*) add_list($#): count(list) = 0 and copy_list(#/self::*) or list[add_list(#/self::*)] or true() copy_list($#): count(#/list) = 0 or create(list[@data = #/list/@data]) and (list[copy_list(#/list)] or true())
et ajoutez-y le XPath appelant:
concat_list(/a/b,/a/c)
J'espÚre que, chers lecteurs, il vous sera un peu intéressant de comprendre un tel "code". La seule chose que je mentionnerai certainement est
create (XPATH) est une fonction systÚme qui exécute son argument XPATH en mode construction.
Et maintenant que tout cela est intéressant, bien sûr, mais la programmation sans variables est encore assez difficile. Comprenant cela, j'ai introduit des variables à part entiÚre, qui, en fait, dans XPath existent déjà - elles commencent par le signe "$", mais j'ai ajouté la possibilité de leur attribuer des valeurs avec la nouvelle fonction set. S'il vous plaßt, voici un exemple de la fonction depth_list avec deux arguments - une référence à l'élément initial contenant une liste imbriquée d'éléments (comme dans l'exemple ci-dessus), et une variable de sortie qui contient la longueur de la liste:
depth_list($#, &$OUT1): set($OUT1,0) and (#/list[set($OUT1,1) and depth_list(#/list,$OUT0) and set($OUT1,max($OUT0+1,$OUT1))]) or true()
Conclusion
Dans le micro-langage résultant, que j'ai appelé
XPath Defender , j'ai ajoutĂ© quelques fonctions plus nĂ©cessaires et l'ai utilisĂ© dans mon systĂšme pour reconnaĂźtre et gĂ©nĂ©rer des programmes PGEN ++ pour effectuer une tĂąche aussi importante que l'achĂšvement automatique du modĂšle d'un programme prĂ©sentĂ© comme un document XML. En d'autres termes, s'il existe une description textuelle d'un problĂšme (pour ĂȘtre dĂ©finitif, en russe), pour la solution duquel il est nĂ©cessaire de gĂ©nĂ©rer un programme, alors cette description est reconnue et se transforme en un ensemble ordonnĂ© d'Ă©lĂ©ments d'Ă©noncĂ© de tĂąche (objets avec paramĂštres). Il s'agit de la dĂ©claration initiale, qui ne contient pas encore de plan pour rĂ©soudre le problĂšme. Les Ă©lĂ©ments reconnus sont placĂ©s dans un document XML et les rĂšgles leur sont appliquĂ©es, Ă©crites Ă la fois sous forme de dĂ©limitation simple ou de gĂ©nĂ©ration d'instructions XPath, et sous forme de fragments sur XPath Defender (c'est l'une des options du workflow). Ces rĂšgles valident et complĂštent le modĂšle de document XML avec des Ă©lĂ©ments d'un plan de solution. Et alors seulement, selon le modĂšle obtenu, le systĂšme construit un programme dĂ©cisif. Ce circuit a Ă©tĂ© testĂ© avec succĂšs sur des problĂšmes simples de traitement mathĂ©matique de donnĂ©es vectorielles.
Mais encore, le résultat le plus important, je pense, est le fait qu'il a été possible de prouver qu'il est possible de construire un langage de programmation algorithmique, en utilisant presque exclusivement les moyens de l'habituel et en construisant XPath, il a fallu introduire uniquement des fonctions.