URL: https://linuxfr.org/forums/programmationautre/posts/ocaml-descente-dun-arbre-xml Title: [OCAML] Descente d'un arbre xml Authors: Ontologia Date: 2009年03月16日T00:31:06+01:00 Tags: Score: -1 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 £spaces£ £/spaces£| [] -> [] £spaces£ £/spaces£| t::q -> match t with £spaces£ £/spaces£| Element(_,_,y::z) -> fusion (node t) (fusion (foreachXml(children t)) (foreachXml(q))) £spaces£ £/spaces£| Element(_,_,y::[]) -> node t £spaces£ £/spaces£| Element(_,_,[]) -> [] £spaces£ £/spaces£| PCData _ -> [];; (* Renvoi :*) Et là, ça marche pas comme j'aimerai £spaces£ £/spaces£| 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", [], []); £spaces£ £/spaces£ Element ("Field1c", [], []); Element ("Field1d", [], []); £spaces£ £/spaces£ Element £spaces£ £/spaces£ ("Field1", [], £spaces£ £/spaces£ [Element ("Field2a", [], []); Element ("Field2b", [], []); £spaces£ £/spaces£ Element ("Field2c", [], [])] ) ] £spaces£ £/spaces£);; 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 !