9 type query_tree = Binop of op * query_tree * query_tree
10 | Axis of Xpath.Ast.axis * query_tree
14 and op = Union | Inter | Diff
17 parametres : tree l'arbre xml
20 retour :un noeud qui correspond à la relation r
23 let print_node_list tree l =
24 List.iter (fun node ->
25 Naive_tree.print_xml stdout tree node
29 let rec print_query_tree fmt q =
31 Dom -> Format.fprintf fmt "Dom"
32 | Start -> Format.fprintf fmt "Start"
33 | Tag t -> Format.fprintf fmt "Tag(%a)" QNameSet.print t
35 Format.fprintf fmt "%a(%a)" Xpath.Ast.print_axis a print_query_tree q
37 Format.fprintf fmt "%a(%a, %a)"
42 and print_binop fmt o =
44 | Union -> Format.fprintf fmt "Union"
45 | Inter -> Format.fprintf fmt "Inter"
46 | Diff -> Format.fprintf fmt "Diff"
48 let rec eval_relation tree m n =
51 | Firstchild -> Naive_tree.first_child tree n
52 | Nextsibling -> Naive_tree.next_sibling tree n
53 | Revfirstchild -> Naive_tree.parent_of_first tree n
54 | Prevsibling -> Naive_tree.prev_sibling tree n
57 parametres : tree l'arbre xml
58 ls l'ensemble de noeuds
60 retour : l'ensemble de noeuds qui correspondent à la relation r
64 let compare_node tree a b =
65 compare (Naive_tree.preorder tree a ) (Naive_tree.preorder tree b )
67 let rec eval_move tree ls m =
70 | r -> List.filter (fun n -> n != Naive_tree.nil)
71 (List.map (eval_relation tree r) ls)
75 parametres : tree l'arbre xml
76 ls l'ensemble de noeuds
78 retour : l'ensemble de noeuds qui correspondent à des relations lr
81 and eval_star tree ls lr =
82 let h = Hashtbl.create 17 in
83 let q = Queue.create () in
84 List.iter ( fun e -> Queue.add e q ) ls;
85 while not (Queue.is_empty q ) do
86 let n = Queue.pop q in
87 if not (Hashtbl.mem h n) then begin
89 List.iter ( fun r -> let m = eval_relation tree r n in
90 if m != Naive_tree.nil && not (Hashtbl.mem h m ) then begin
96 let l = Hashtbl.fold (fun k _ acc -> k::acc) h [] in
97 List.sort (compare_node tree) l
100 parametres : tree l'arbre xml
101 ls l'ensemble de noeuds
103 retour : l'ensemble de noeuds qui correspondent à l'axe
106 let keep_elements t l =
107 List.filter (fun n -> match Naive_tree.kind t n with
108 | Element | Text | Document -> true | _ -> false) l
110 let rec eval_axis tree ls a =
111 let open Xpath.Ast in
113 (* let ls = List.sort ( fun a b -> compare (Naive_tree.preorder tree a ) (Naive_tree.preorder tree b ) ) ls in écrir dans la log!!!!!*)
117 | Attribute -> assert false
119 | Child -> let lfc = eval_move tree ls Firstchild in
120 eval_star tree lfc [Nextsibling]
122 | Descendant c -> let lfc = eval_move tree ls Firstchild in
123 let ls2 = eval_star tree lfc [Firstchild;Nextsibling] in
125 (* List.merge (compare_node tree) (if c then ls else [])
126 (List.merge (compare_node tree) ls2 ls)*)
129 else List.merge (compare_node tree) ls2 ls
131 | FollowingSibling -> let lnexts = eval_move tree ls Nextsibling in
132 eval_star tree lnexts [Nextsibling]
134 | Parent -> let lprevs = eval_star tree ls [Prevsibling] in
135 eval_move tree lprevs Revfirstchild
137 | Ancestor b -> let ls2 = eval_star tree ls [Revfirstchild;Prevsibling] in
138 let ls3 = eval_move tree ls2 Revfirstchild in
140 else List.merge (compare_node tree ) ls3 ls
142 | PrecedingSibling -> let ls2 = eval_star tree ls [Prevsibling] in
143 eval_move tree ls2 Prevsibling
145 | Preceding -> let ls2 = eval_axis tree ls (Ancestor true) in
146 let ls3 = eval_axis tree ls2 PrecedingSibling in
147 eval_axis tree ls3 (Descendant true)
149 | Following -> let ls2 = eval_axis tree ls (Ancestor true) in
150 let ls3 = eval_axis tree ls2 FollowingSibling in
151 eval_axis tree ls3 (Descendant true)
153 keep_elements tree res