Forum Programmation.autre [OCAML] Descente d'un arbre xml

Posté par  (site web personnel) .
Étiquettes : aucune
-1
16
mar.
2009
Bonjour, OCaml c'est génial, mais faut bien s'accrocher :-)

Je cherche à traiter un arbre xml issu du parsing d'un fichier avec la librairie xml-light.
La structure de donnée sur laquelle je travaille est simplissime :

type xml =
| Element of (string * (string * string) list * xml list) (* ie le nom, la liste des attributs et les enfants)
| PCData of string

Je précise ici que je n'ai et n'aurai jamais à traiter le cas PCData dans le projet sur lequel je travaille, étant donné que la DTD du xml que je parse n'utilise que des balises du type (avec plusieurs attributs parfois).

Ce xml représente un arbre syntaxique abstrait d'un programme (java en l'occurence, mais ça importe peu ici).
Je veux descendre l'arbre, pour - pour le moment - cracher la liste des couples d'attributs de TOUT les noeuds, soit une (string * string) list mais dans l'ordre de descente de l'arbre (par la suite j'aimerai reconstruire une grammaire sur un type somme adequat, mais j'imagine que quand ça ça marchera, ça sera un bon début)

J'ai les fonction children : Xml.xml -> Xml.xml list et fusion : `a list -> `a list -> `a list qui bien évidemment renvoient respectivement le sous arbre d'un noeuds et fusionne deux listes

node est la fonction qui me renvoi la liste d'attributs d'un noeud.
val node : Xml.xml -> (string * string) list =


J'ai écrit le code suivant :


let rec descent (tree:Xml.xml) = match tree with
| Element(_,_,t::q) -> fusion (node t) (fusion (foreachXml (children t)) (foreachXml q))
| Element(_,_,[]) -> []
| PCData _ -> [];;

(* Renvoi : val descent : Xml.xml -> (string * string) list = *)

et

let rec foreachXml (treelist:(Xml.xml list)) = match treelist with
| [] -> []
| t::q -> match t with
| Element(_,_,y::z) -> fusion (node t) (fusion (foreachXml(children t)) (foreachXml(q)))
| Element(_,_,y::[]) -> node t
| Element(_,_,[]) -> []
| PCData _ -> [];;
(* Renvoi :*)

Et là, ça marche pas comme j'aimerai

| Element(_,_,y::[]) -> node t
Warning U: this match case is unused.
val foreachXml : Xml.xml list -> (string * string) list =


En gros, il sort qq chose ds certains cas, mais s'arrête à une profondeur d'environ 3.
En traçant la fonction, je vois bien qu'il descend tout l'arbre, mais il remonte que peu de choses
Or c'est précisément ce cas là qui m'intéresse, car je voudrai être sur que toutes mes feuilles "remontent"...
Par exemple ce cas renvoi vide :
let el = Element
  ("field", [("name", "MULTILINE"); ("visibility", "public")],
   [Element ("Field1a", [], []); Element ("Field1b", [], []);
   Element ("Field1c", [], []); Element ("Field1d", [], []);
   Element
    ("Field1", [],
     [Element ("Field2a", [], []); Element ("Field2b", [], []);
     Element ("Field2c", [], [])]
   )
   ]
);;


Ca fait quelques heures que je tourne autour du pot, pas très habitué que je suis à ce langage (10 ans sans y toucher c'est long ;-) , si vous aviez un coup de pouce...

Merci !
  • # GRRRRRRRRR

    Posté par  (site web personnel) . Évalué à 3.

    let rec toAttr = function
    | Element( s , a , [] ) -> a
    | Element( s , a , p::q ) -> fusion (fusion a (toAttr p)) (List.concat (List.map toAttr q))
    | PCData s -> [] ;;


    Evidemment ça fait 3 lignes....

    12h d'arrachage de cheveux pour ça.
    Moi pas doué :-(

    Bon, c'était mon deuxième baptème du feu !

    « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.