Déduire les enfants possible à partir d'un schéma RELAX NG

a marqué ce sujet comme résolu.

Salut,

Je cherche, donné un arbre XML et un schéma RELAX NG, à suggérer un noeud enfant de l’arbre, en garantissant que celui-ci est valide selon le schéma.

Imagions la situation suivante:

schema.rng:

<?xml version="1.0" encoding="utf-8"?>
<grammar>
  <start>
    <ref name="node.zds" />
  </start>
  <define name="node.zds">
    <element name="zds">
      <interleave>
        <ref name="node.a" />
        <ref name="node.b" />
      </interleave>
    </element>
  </define>
  <define name="node.a">
    <element name="a">
      <text />
    </element>
  </define>
  <define name="node.b">
    <element name="b">
      <text />
    </element>
  </define>
</grammar>

zds.xml:

<?xml version="1.0" encoding="utf-8"?>
<zds>
  <b>hello world</b>
</zds>

Je souhaite donc obtenir une fonction suggest(node: Node): string[] fournissant les suggestions pour le noeud node. Par exemple, ici, j’aimerais obtenir ['a'] en sortie de suggest(zds).

Et je galère.

Mon idée est d’avoir une fonction récursive suggest(rngPointer: Node, xmlPointer: Node) qui me retourne un objet { suggestions: string[], consume: { rng: { type: "jump", to: Node } | { type: "boolean", value: boolean }, xml: boolean }, qui me permet d’avoir une boucle infinie, qui avance selon les valeurs de consume.
Mais les problèmes arrivent dès qu’il ne s’agit plus d’avancer de façon linéaire. Je gère assez bien les ref/define avec le jump, mais les choses se corsent avec les choice, interleave, et autres.

(À noter que je simplifie le RNG à l’avance pour garantir de n’avoir que deux enfants à chacun des choice, interleave, group, etc., et que je remplace les optional, zeroOrMore par leurs équivalences à l’aide de choice).

Pour l’instant, pour gérer un interleave, je lance deux suggest, un pour chaque enfant, et je regarde celui qui consume un noeud xml. Sauf que bien sûr, ça a ses limites: ça ne fonctionne pas du moment que l’enfant direct du interleave n’est pas un element. Et je crois que c’est plutôt une limite de la façon dont j’encode le problème.

Est-ce que vous connaissez des problèmes analogues avec des façons <<classiques>> de les résoudre, ou avez une idée de comment <<bien>> résoudre ce problème?

Le vrai code se trouve sur Github https://github.com/dvbmgr/robin4.

Merci d’avance !

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte