8 type query_tree_desc = Binop of op * query_tree * query_tree
9 | Axis of Xpath.Ast.axis * query_tree
12 | Tag of QNameSet.t * Tree.NodeKind.t
14 and op = Union | Inter | Diff
17 mutable desc : query_tree_desc;
29 parametres : tree l'arbre xml
32 retour :un noeud qui correspond ॆ la relation r
35 let print_node_list tree l =
36 List.iter (fun node ->
37 Naive_tree.print_xml stdout tree node;
41 let rec print_query_tree fmt q =
43 Dom -> Format.fprintf fmt "Dom"
44 | Start -> Format.fprintf fmt "Start"
45 | Tag (t,k) -> Format.fprintf fmt "Tag(%a, %a)" QNameSet.print t Tree.NodeKind.print k
47 Format.fprintf fmt "%a(%a)" Xpath.Ast.print_axis a print_query_tree q
49 Format.fprintf fmt "%a(%a, %a)"
54 and print_binop fmt o =
56 | Union -> Format.fprintf fmt "Union"
57 | Inter -> Format.fprintf fmt "Inter"
58 | Diff -> Format.fprintf fmt "Diff"
60 let rec eval_relation tree m n =
63 | Firstchild -> Naive_tree.first_child tree n
64 | Nextsibling -> Naive_tree.next_sibling tree n
65 | Revfirstchild -> Naive_tree.parent_of_first tree n
66 | Prevsibling -> Naive_tree.prev_sibling tree n
69 parametres : tree l'arbre xml
70 ls l'ensemble de noeuds
72 retour : l'ensemble de noeuds qui correspondent ॆ la relation r
76 let compare_node tree a b =
77 compare (Naive_tree.preorder tree a ) (Naive_tree.preorder tree b )
79 let rec eval_move tree ls m =
82 | r -> List.filter (fun n -> n != Naive_tree.nil)
83 (List.map (eval_relation tree r) ls)
87 parametres : tree l'arbre xml
88 ls l'ensemble de noeuds
90 retour : l'ensemble de noeuds qui correspondent ॆ des relations lr
93 and eval_star tree ls lr =
94 let h = Hashtbl.create 17 in
95 let q = Queue.create () in
96 List.iter ( fun e -> Queue.add e q ) ls;
97 while not (Queue.is_empty q ) do
98 let n = Queue.pop q in
99 if not (Hashtbl.mem h n) then begin
101 List.iter ( fun r -> let m = eval_relation tree r n in
102 if m != Naive_tree.nil && not (Hashtbl.mem h m ) then begin
108 let l = Hashtbl.fold (fun k _ acc -> k::acc) h [] in
109 List.sort (compare_node tree) l
112 parametres : tree l'arbre xml
113 ls l'ensemble de noeuds
115 retour : l'ensemble de noeuds qui correspondent ॆ l'axe
118 let keep_elements t l = (*
119 List.filter (fun n -> match Naive_tree.kind t n with
120 | Element | Text | Document | Attribute -> true | _ -> false) l
123 let keep_attributs t l = (*
124 List.filter (fun n -> match Naive_tree.kind t n with
125 | Attribute ->true | _ -> false) *) l
127 let rec eval_axis tree ls a =
128 let open Xpath.Ast in
132 | Attribute -> let lfc = eval_move tree ls Firstchild in
133 let lc = eval_star tree lfc [Nextsibling] in
134 keep_attributs tree lc
136 | Child -> let lfc = eval_move tree ls Firstchild in
137 let lc = eval_star tree lfc [Nextsibling] in
138 keep_elements tree lc
140 | Descendant c -> let lfc = eval_move tree ls Firstchild in
141 let ls2 = eval_star tree lfc [Firstchild;Nextsibling] in
144 else List.merge (compare_node tree) ls2 ls
146 keep_elements tree ldes
148 | FollowingSibling -> let lnexts = eval_move tree ls Nextsibling in
149 let lfs = eval_star tree lnexts [Nextsibling] in
150 keep_elements tree lfs
152 | Parent -> let lprevs = eval_star tree ls [Prevsibling] in
153 let lp = eval_move tree lprevs Revfirstchild in
154 keep_elements tree lp
156 | Ancestor b -> let ls2 = eval_star tree ls [Revfirstchild;Prevsibling] in
157 let ls3 = eval_move tree ls2 Revfirstchild in
160 else List.merge (compare_node tree ) ls3 ls
162 keep_elements tree lac
164 | PrecedingSibling -> let ls2 = eval_star tree ls [Prevsibling] in
165 let lps = eval_move tree ls2 Prevsibling in
166 keep_elements tree lps
168 | Preceding -> let ls2 = eval_axis tree ls (Ancestor true) in
169 let ls3 = eval_axis tree ls2 PrecedingSibling in
170 let lp = eval_axis tree ls3 (Descendant true) in
171 keep_elements tree lp
173 | Following -> let ls2 = eval_axis tree ls (Ancestor true) in
174 let ls3 = eval_axis tree ls2 FollowingSibling in
175 let lf = eval_axis tree ls3 (Descendant true) in
176 keep_elements tree lf