8 type query_tree = Binop of op * query_tree * query_tree
9 | Axis of Xpath.Ast.axis * query_tree
13 and op = Union | Inter | Diff
16 parametres : tree l'arbre xml
19 retour :un noeud qui correspond ॆ la relation r
22 let print_node_list tree l =
23 List.iter (fun node ->
24 Naive_tree.print_xml stdout tree node;
28 let rec print_query_tree fmt q =
30 Dom -> Format.fprintf fmt "Dom"
31 | Start -> Format.fprintf fmt "Start"
32 | Tag t -> Format.fprintf fmt "Tag(%a)" QNameSet.print t
34 Format.fprintf fmt "%a(%a)" Xpath.Ast.print_axis a print_query_tree q
36 Format.fprintf fmt "%a(%a, %a)"
41 and print_binop fmt o =
43 | Union -> Format.fprintf fmt "Union"
44 | Inter -> Format.fprintf fmt "Inter"
45 | Diff -> Format.fprintf fmt "Diff"
47 let rec eval_relation tree m n =
50 | Firstchild -> Naive_tree.first_child tree n
51 | Nextsibling -> Naive_tree.next_sibling tree n
52 | Revfirstchild -> Naive_tree.parent_of_first tree n
53 | Prevsibling -> Naive_tree.prev_sibling tree n
56 parametres : tree l'arbre xml
57 ls l'ensemble de noeuds
59 retour : l'ensemble de noeuds qui correspondent ॆ la relation r
63 let compare_node tree a b =
64 compare (Naive_tree.preorder tree a ) (Naive_tree.preorder tree b )
66 let rec eval_move tree ls m =
69 | r -> List.filter (fun n -> n != Naive_tree.nil)
70 (List.map (eval_relation tree r) ls)
74 parametres : tree l'arbre xml
75 ls l'ensemble de noeuds
77 retour : l'ensemble de noeuds qui correspondent ॆ des relations lr
80 and eval_star tree ls lr =
81 let h = Hashtbl.create 17 in
82 let q = Queue.create () in
83 List.iter ( fun e -> Queue.add e q ) ls;
84 while not (Queue.is_empty q ) do
85 let n = Queue.pop q in
86 if not (Hashtbl.mem h n) then begin
88 List.iter ( fun r -> let m = eval_relation tree r n in
89 if m != Naive_tree.nil && not (Hashtbl.mem h m ) then begin
95 let l = Hashtbl.fold (fun k _ acc -> k::acc) h [] in
96 List.sort (compare_node tree) l
99 parametres : tree l'arbre xml
100 ls l'ensemble de noeuds
102 retour : l'ensemble de noeuds qui correspondent ॆ l'axe
105 let keep_elements t l =
106 List.filter (fun n -> match Naive_tree.kind t n with
107 | Element | Text | Document | Attribute -> true | _ -> false) l
109 let keep_attributs t l =
110 List.filter (fun n -> match Naive_tree.kind t n with
111 | Attribute ->true | _ -> false) l
113 let rec eval_axis tree ls a =
114 let open Xpath.Ast in
116 Self -> keep_elements tree ls
118 | Attribute -> let lfc = eval_move tree ls Firstchild in
119 let lc = eval_star tree lfc [Nextsibling] in
120 keep_attributs tree lc
122 | Child -> let lfc = eval_move tree ls Firstchild in
123 let lc = eval_star tree lfc [Nextsibling] in
124 keep_elements tree lc
126 | Descendant c -> let lfc = eval_move tree ls Firstchild in
127 let ls2 = eval_star tree lfc [Firstchild;Nextsibling] in
130 else List.merge (compare_node tree) ls2 ls
132 keep_elements tree ldes
134 | FollowingSibling -> let lnexts = eval_move tree ls Nextsibling in
135 let lfs = eval_star tree lnexts [Nextsibling] in
136 keep_elements tree lfs
138 | Parent -> let lprevs = eval_star tree ls [Prevsibling] in
139 let lp = eval_move tree lprevs Revfirstchild in
140 keep_elements tree lp
142 | Ancestor b -> let ls2 = eval_star tree ls [Revfirstchild;Prevsibling] in
143 let ls3 = eval_move tree ls2 Revfirstchild in
146 else List.merge (compare_node tree ) ls3 ls
148 keep_elements tree lac
150 | PrecedingSibling -> let ls2 = eval_star tree ls [Prevsibling] in
151 let lps = eval_move tree ls2 Prevsibling in
152 keep_elements tree lps
154 | Preceding -> let ls2 = eval_axis tree ls (Ancestor true) in
155 let ls3 = eval_axis tree ls2 PrecedingSibling in
156 let lp = eval_axis tree ls3 (Descendant true) in
157 keep_elements tree lp
159 | Following -> let ls2 = eval_axis tree ls (Ancestor true) in
160 let ls3 = eval_axis tree ls2 FollowingSibling in
161 let lf = eval_axis tree ls3 (Descendant true) in
162 keep_elements tree lf