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 listesnode 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 Ontologia (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.