8 type query_tree = Binop of op * query_tree * query_tree
9 | Axis of Xpath.Ast.axis * query_tree
12 | Tag of QNameSet.t * Tree.NodeKind.t
13 and op = Union | Inter | Diff
15 mutable desc : query_tree_desc;
27 parametres : tree l'arbre xml
30 retour :un noeud qui correspond ॆ la relation r
33 let print_node_list tree l =
34 List.iter (fun node ->
35 Naive_tree.print_xml stdout tree node;
39 let rec print_query_tree fmt q =
41 Dom -> Format.fprintf fmt "Dom"
42 | Start -> Format.fprintf fmt "Start"
43 | Tag (t,k) -> Format.fprintf fmt "Tag(%a, %a)" QNameSet.print t Tree.NodeKind.print k
45 Format.fprintf fmt "%a(%a)" Xpath.Ast.print_axis a print_query_tree q
47 Format.fprintf fmt "%a(%a, %a)"
52 and print_binop fmt o =
54 | Union -> Format.fprintf fmt "Union"
55 | Inter -> Format.fprintf fmt "Inter"
56 | Diff -> Format.fprintf fmt "Diff"
58 let rec eval_relation tree m n =
61 | Firstchild -> Naive_tree.first_child tree n
62 | Nextsibling -> Naive_tree.next_sibling tree n
63 | Revfirstchild -> Naive_tree.parent_of_first tree n
64 | Prevsibling -> Naive_tree.prev_sibling tree n
67 parametres : tree l'arbre xml
68 ls l'ensemble de noeuds
70 retour : l'ensemble de noeuds qui correspondent ॆ la relation r
74 let compare_node tree a b =
75 compare (Naive_tree.preorder tree a ) (Naive_tree.preorder tree b )
77 let rec eval_move tree ls m =
80 | r -> List.filter (fun n -> n != Naive_tree.nil)
81 (List.map (eval_relation tree r) ls)
85 parametres : tree l'arbre xml
86 ls l'ensemble de noeuds
88 retour : l'ensemble de noeuds qui correspondent ॆ des relations lr
91 and eval_star tree ls lr =
92 let h = Hashtbl.create 17 in
93 let q = Queue.create () in
94 List.iter ( fun e -> Queue.add e q ) ls;
95 while not (Queue.is_empty q ) do
96 let n = Queue.pop q in
97 if not (Hashtbl.mem h n) then begin
99 List.iter ( fun r -> let m = eval_relation tree r n in
100 if m != Naive_tree.nil && not (Hashtbl.mem h m ) then begin
106 let l = Hashtbl.fold (fun k _ acc -> k::acc) h [] in
107 List.sort (compare_node tree) l
110 parametres : tree l'arbre xml
111 ls l'ensemble de noeuds
113 retour : l'ensemble de noeuds qui correspondent ॆ l'axe
116 let keep_elements t l = (*
117 List.filter (fun n -> match Naive_tree.kind t n with
118 | Element | Text | Document | Attribute -> true | _ -> false) l
121 let keep_attributs t l = (*
122 List.filter (fun n -> match Naive_tree.kind t n with
123 | Attribute ->true | _ -> false) *) l
125 let rec eval_axis tree ls a =
126 let open Xpath.Ast in
130 | Attribute -> let lfc = eval_move tree ls Firstchild in
131 let lc = eval_star tree lfc [Nextsibling] in
132 keep_attributs tree lc
134 | Child -> let lfc = eval_move tree ls Firstchild in
135 let lc = eval_star tree lfc [Nextsibling] in
136 keep_elements tree lc
138 | Descendant c -> let lfc = eval_move tree ls Firstchild in
139 let ls2 = eval_star tree lfc [Firstchild;Nextsibling] in
142 else List.merge (compare_node tree) ls2 ls
144 keep_elements tree ldes
146 | FollowingSibling -> let lnexts = eval_move tree ls Nextsibling in
147 let lfs = eval_star tree lnexts [Nextsibling] in
148 keep_elements tree lfs
150 | Parent -> let lprevs = eval_star tree ls [Prevsibling] in
151 let lp = eval_move tree lprevs Revfirstchild in
152 keep_elements tree lp
154 | Ancestor b -> let ls2 = eval_star tree ls [Revfirstchild;Prevsibling] in
155 let ls3 = eval_move tree ls2 Revfirstchild in
158 else List.merge (compare_node tree ) ls3 ls
160 keep_elements tree lac
162 | PrecedingSibling -> let ls2 = eval_star tree ls [Prevsibling] in
163 let lps = eval_move tree ls2 Prevsibling in
164 keep_elements tree lps
166 | Preceding -> let ls2 = eval_axis tree ls (Ancestor true) in
167 let ls3 = eval_axis tree ls2 PrecedingSibling in
168 let lp = eval_axis tree ls3 (Descendant true) in
169 keep_elements tree lp
171 | Following -> let ls2 = eval_axis tree ls (Ancestor true) in
172 let ls3 = eval_axis tree ls2 FollowingSibling in
173 let lf = eval_axis tree ls3 (Descendant true) in
174 keep_elements tree lf