/[svn]/schema/schema_parser.ml
ViewVC logotype

Contents of /schema/schema_parser.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 892 - (show annotations)
Tue Jul 10 18:09:35 2007 UTC (5 years, 10 months ago) by abate
File size: 31750 byte(s)
[r2003-11-30 14:27:07 by beppe] add url support for load_xml, load_html and in schema declarations

Original author: beppe
Date: 2003-11-30 14:27:08+00:00
1
2 open Printf
3 open Pxp_document
4
5 open Encodings
6 open Encodings.Utf8.Pcre
7 open Schema_common
8 open Schema_types
9 open Schema_validator
10 open Schema_xml
11 open Schema_xml.Pxp_helpers
12
13 let debug = false
14 let debug_print ?(n: pxp_node option) s =
15 if debug then
16 (match n with
17 | None -> prerr_endline s
18 | Some n ->
19 let line = match n#position with (_,l,_) -> l in
20 prerr_endline (sprintf "[%d] %s" line s);
21 flush stderr)
22
23 let space_RE = pcre_regexp " "
24 let split s = pcre_split ~rex:space_RE s
25 let unqualify s = snd (Ns.split_qname s)
26 let hashtbl_deref tbl =
27 (* ASSUMPTION: no multiple bindings *)
28 let tbl' = Hashtbl.create 1024 in
29 Hashtbl.iter (fun key value -> Hashtbl.add tbl' key !value) tbl;
30 tbl'
31 let hashtbl_values tbl = Hashtbl.fold (fun _ v acc -> v :: acc) tbl []
32
33 class type resolver =
34 object
35 (** add a node to the list of "seen" nodes.
36 @raise Osv_validation_error if the same node is seen twice *)
37 method see : pxp_node -> unit
38
39 method resolve_att: ?fix_ns:bool -> Utf8.t -> attribute_declaration
40 method resolve_elt:
41 ?fix_ns:bool -> now:bool -> Utf8.t -> element_declaration ref
42 method resolve_typ:
43 ?fix_ns:bool -> now:bool -> Utf8.t -> type_definition ref
44 method resolve_att_group:
45 ?fix_ns:bool -> Utf8.t -> attribute_group_definition
46 method resolve_model_group: ?fix_ns:bool -> Utf8.t -> model_group_definition
47 method resolve_simple_typ: ?fix_ns:bool -> Utf8.t -> simple_type_definition
48 end
49
50 module OrderedNode =
51 struct
52 type t = pxp_node
53 let compare = Pxp_document.compare
54 end
55 module NodeSet = Set.Make (OrderedNode)
56
57 (* element and complex type constructors which take cares of unique id *)
58 let element, complex =
59 let counter = ref 0 in
60 let element name (type_def: type_definition ref) constr =
61 incr counter;
62 !counter, name, type_def, constr
63 in
64 let complex name (type_def: type_definition) deriv attrs ct =
65 incr counter;
66 !counter, name, type_def, deriv, attrs, ct
67 in
68 (element, complex)
69
70 let integer_of_value_t = function
71 | Value.Integer i -> i
72 | _ -> assert false
73
74 let parse_facets base n =
75 debug_print ~n "Schema_parser.parse_facet";
76 let validate_base_type = Schema_validator.validate_simple_type base in
77 let validate_nonNegativeInteger =
78 Schema_builtin.validate_builtin
79 (Schema_xml.add_xsd_prefix (Utf8.mk "nonNegativeInteger"))
80 in
81 let facets = ref no_facets in
82 n#iter_nodes (fun n ->
83 let fixed =
84 (_has_attribute "fixed" n) && (_attribute "fixed" n = Utf8.mk "true")
85 in
86 match n#node_type with
87 | T_element "xsd:length" ->
88 let value = _attribute "value" n in
89 let length = integer_of_value_t (validate_nonNegativeInteger value) in
90 facets := { !facets with length = Some (length, fixed) }
91 | T_element "xsd:minLength" ->
92 let value = _attribute "value" n in
93 let length = integer_of_value_t (validate_nonNegativeInteger value) in
94 facets := { !facets with minLength = Some (length, fixed) }
95 | T_element "xsd:maxLength" ->
96 let value = _attribute "value" n in
97 let length = integer_of_value_t (validate_nonNegativeInteger value) in
98 facets := { !facets with maxLength = Some (length, fixed) }
99 | T_element "xsd:enumeration" ->
100 let value = Value.string_utf8 (_attribute "value" n) in
101 let value = validate_base_type value in
102 let new_enumeration =
103 (match !facets.enumeration with
104 | None -> Some (Value.ValueSet.singleton value)
105 | Some entries -> Some (Value.ValueSet.add value entries))
106 in
107 facets := { !facets with enumeration = new_enumeration }
108 | T_element "xsd:whiteSpace" ->
109 let value = Utf8.get_str (_attribute "value" n) in
110 facets := { !facets with whiteSpace =
111 ((match value with
112 | "collapse" -> `Collapse
113 | "preserve" -> `Preserve
114 | "replace" -> `Replace
115 | _ -> assert false),
116 fixed) }
117 | T_element "xsd:maxInclusive" ->
118 let value = Value.string_utf8 (_attribute "value" n) in
119 facets := { !facets with
120 maxInclusive = Some (validate_base_type value, fixed) }
121 | T_element "xsd:maxExclusive" ->
122 let value = Value.string_utf8 (_attribute "value" n) in
123 facets := { !facets with
124 maxExclusive = Some (validate_base_type value, fixed) }
125 | T_element "xsd:minInclusive" ->
126 let value = Value.string_utf8 (_attribute "value" n) in
127 facets := { !facets with
128 minInclusive = Some (validate_base_type value, fixed) }
129 | T_element "xsd:minExclusive" ->
130 let value = Value.string_utf8 (_attribute "value" n) in
131 facets := { !facets with
132 minExclusive = Some (validate_base_type value, fixed) }
133 | _ -> ());
134 !facets
135
136 let merge_facets' base new_facets =
137 merge_facets (facets_of_simple_type_definition base) new_facets
138
139 (* parse an xsd:simpleType element *)
140 let rec parse_simple_type (resolver: resolver) n =
141 debug_print ~n "Schema_parser.parse_simple_type";
142 resolver#see n;
143 let name =
144 if _has_attribute "name" n then Some (_attribute "name" n) else None
145 in
146 if _has_element "xsd:restriction" n then begin (* restriction *)
147 let restriction = _element "xsd:restriction" n in
148 let base = find_base_simple_type resolver restriction in
149 let facets = parse_facets base restriction in
150 restrict base facets name
151 end else if _has_element "xsd:list" n then begin (* list *)
152 let list = _element "xsd:list" n in
153 let items = find_item_type resolver list in
154 Derived (name, List items, no_facets, anySimpleType)
155 end else begin (* union *)
156 let union = _element "xsd:union" n in
157 let members = find_member_types resolver union in
158 Derived (name, Union members, no_facets, anySimpleType)
159 end
160
161 (* look for a simple type def: try attribute "base", try "simpleType" child,
162 * fail *)
163 and find_base_simple_type (resolver: resolver) n =
164 if _has_attribute "base" n then
165 resolver#resolve_simple_typ (_attribute "base" n)
166 else if _has_element "xsd:simpleType" n then
167 parse_simple_type resolver (_element "xsd:simpleType" n)
168 else
169 raise (XSD_validation_error "no base simple type specified")
170
171 (* look for a simple type def: try attribute "itemType", try "simpleType"
172 * child, fail *)
173 and find_item_type (resolver: resolver) n =
174 if _has_attribute "itemType" n then
175 resolver#resolve_simple_typ (_attribute "itemType" n)
176 else if _has_element "xsd:simpleType" n then
177 parse_simple_type resolver (_element "xsd:simpleType" n)
178 else
179 raise (XSD_validation_error "no itemType specified")
180
181 (* look for a list of simple type defs: try attribute "memberTypes", try
182 * "simpleType" children, fail *)
183 and find_member_types (resolver: resolver) n =
184 let members1 =
185 if _has_attribute "memberTypes" n then
186 let names = split (_attribute "memberTypes" n) in
187 List.map resolver#resolve_simple_typ names
188 else
189 []
190 in
191 let members2 =
192 let nodes = _elements "xsd:simpleType" n in
193 List.map (parse_simple_type resolver) nodes
194 in
195 (match members1 @ members2 with
196 | [] -> raise (XSD_validation_error "no member types specified")
197 | members -> members)
198
199 (* parse an attribute value constraint *)
200 let parse_att_value_constraint stype_def n =
201 debug_print ~n "Schema_parser.parse_att_value_constraint";
202 if _has_attribute "default" n then
203 let value = Value.string_utf8 (_attribute "default" n) in
204 let value = validate_simple_type stype_def value in
205 Some (`Default value)
206 else if _has_attribute "fixed" n then
207 let value = Value.string_utf8 (_attribute "fixed" n) in
208 let value = validate_simple_type stype_def value in
209 Some (`Fixed value)
210 else
211 None
212
213 (* parse an element value constraint *)
214 let parse_elt_value_constraint type_def n =
215 debug_print ~n "Schema_parser.parse_elt_value_constraint";
216 let validate_value =
217 match type_def with
218 | Simple st_def | Complex (_, _, _, _, _, CT_simple st_def) ->
219 validate_simple_type st_def
220 | _ -> validate_simple_type (Primitive (Utf8.mk "xsd:string"))
221 in
222 if _has_attribute "default" n then
223 let value = Value.string_utf8 (_attribute "default" n) in
224 let value = validate_value value in
225 Some (`Default value)
226 else if _has_attribute "fixed" n then
227 let value = Value.string_utf8 (_attribute "fixed" n) in
228 let value = validate_value value in
229 Some (`Fixed value)
230 else
231 None
232
233 (* look for a simple type def, try "simpleType" child, try "type" attribute,
234 * return anySimpleType *)
235 let find_simple_type (resolver: resolver) n =
236 if _has_element "xsd:simpleType" n then
237 parse_simple_type resolver (_element "xsd:simpleType" n)
238 else if _has_attribute "type" n then
239 resolver#resolve_simple_typ (_attribute "type" n)
240 else
241 anySimpleType
242
243 let parse_att_decl (resolver: resolver) n =
244 debug_print ~n "Schema_parser.parse_att_decl";
245 resolver#see n;
246 let name = _attribute "name" n in
247 let type_def = find_simple_type resolver n in
248 let value_constr = parse_att_value_constraint type_def n in
249 name, type_def, value_constr
250
251 let parse_attribute_use (resolver: resolver) n =
252 debug_print ~n "Schema_parser.parse_attribute_use";
253 let required =
254 (_has_attribute "use" n) && (_attribute "use" n = Utf8.mk "required")
255 in
256 let (name, type_def, value_constr) as att_decl =
257 if _has_attribute "ref" n then
258 resolver#resolve_att (_attribute "ref" n)
259 else
260 let (name, type_def, constr) = parse_att_decl resolver n in
261 (name, type_def, None) (* forget attribute value constraint *)
262 in
263 let value_constr = parse_att_value_constraint type_def n in
264 required, att_decl, value_constr
265
266 let parse_attribute_uses (resolver: resolver) derivation_type base n =
267 debug_print ~n "Schema_parser.parse_attribute_uses";
268 let uses1 = (* attribute uses from "attribute" children *)
269 List.map (parse_attribute_use resolver) (_elements "xsd:attribute" n)
270 in
271 let uses2 = (* attribute uses from "attributeGroup" children ref *)
272 List.concat (List.map
273 (fun att_group ->
274 if _has_attribute "ref" att_group then
275 snd (resolver#resolve_att_group (_attribute "ref" att_group))
276 else [])
277 (_elements "xsd:attributeGroup" n))
278 in
279 let uses3 = (* attribute uses from base type *)
280 match base with
281 | Complex (_, _, _, _, uses, _) ->
282 (match derivation_type with
283 | `Extension -> uses
284 | `Restriction ->
285 let ( &= ) u1 u2 = (* by name equality over attribute uses *)
286 (name_of_attribute_use u1 = name_of_attribute_use u2)
287 in
288 let defined_uses = uses1 @ uses2 in
289 List.filter
290 (fun use -> not (List.exists (fun u -> u &= use) defined_uses))
291 (* && not (List.mem name prohibited_uses1) *) (* TODO prohibited attribute uses *)
292 uses)
293 | _ -> []
294 in
295 uses1 @ uses2 @ uses3
296
297 let parse_min_max n =
298 ((if _has_attribute "minOccurs" n then
299 Intervals.V.mk (Utf8.get_str (_attribute "minOccurs" n))
300 else
301 Intervals.V.one),
302 (if _has_attribute "maxOccurs" n then
303 match Utf8.get_str (_attribute "maxOccurs" n) with
304 | "unbounded" -> None
305 | s -> Some (Intervals.V.mk s)
306 else
307 Some Intervals.V.one))
308
309 let find_particles =
310 _elements' ["xsd:element"; "xsd:group"; "xsd:choice"; "xsd:sequence"]
311
312 let rec parse_complex_type (resolver: resolver) n =
313 let find_particle n =
314 try
315 Some (_element' ["xsd:all"; "xsd:choice"; "xsd:group"; "xsd:sequence"] n)
316 with Not_found -> None
317 in
318 debug_print ~n "Schema_parser.parse_complex_type";
319 resolver#see n;
320 let name =
321 if _has_attribute "name" n then Some (_attribute "name" n) else None
322 in
323 if _has_element "xsd:simpleContent" n then
324 let content = _element "xsd:simpleContent" n in
325 let derivation, derivation_type =
326 if _has_element "xsd:restriction" content then
327 (_element "xsd:restriction" content, `Restriction)
328 else (* _has_element "xsd:extension" *)
329 (_element "xsd:extension" content, `Extension)
330 in
331 let base = resolver#resolve_typ ~now:true (_attribute "base" derivation) in
332 let uses = parse_attribute_uses resolver derivation_type !base derivation in
333 let content_type =
334 match derivation_type with
335 | `Restriction ->
336 (match !base with
337 | Complex (_, _, _, _, _, (CT_simple base)) ->
338 let base =
339 if _has_element "xsd:simpleType" derivation then
340 parse_simple_type resolver
341 (_element "xsd:simpleType" derivation)
342 else
343 base
344 in
345 let new_facets = merge_facets' base (parse_facets base n) in
346 let restricted_simple_type_def =
347 (match base with
348 | Primitive name ->
349 Derived (None, variety_of_simple_type_definition base,
350 new_facets, base)
351 | Derived (_, variety, _, _) ->
352 Derived (None, variety, new_facets, base))
353 in
354 CT_simple restricted_simple_type_def
355 | _ -> assert false)
356 | `Extension ->
357 (match !base with
358 | Complex (_, _, _, _, _, (CT_simple base)) -> CT_simple base
359 | Simple simple_type_def -> CT_simple simple_type_def
360 | _ -> assert false)
361 in
362 complex name !base derivation_type uses content_type
363 else if _has_element "xsd:complexContent" n then
364 let content = _element "xsd:complexContent" n in
365 let derivation, derivation_type =
366 if _has_element "xsd:restriction" content then
367 (_element "xsd:restriction" content, `Restriction)
368 else (* _has_element "xsd:extension" *)
369 (_element "xsd:extension" content, `Extension)
370 in
371 let base = resolver#resolve_typ ~now:true (_attribute "base" derivation) in
372 let uses = parse_attribute_uses resolver derivation_type !base derivation in
373 let mixed =
374 (_has_attribute "mixed" content &&
375 (_attribute "mixed" content = Utf8.mk "true"))
376 || (_has_attribute "mixed" n && (_attribute "mixed" n = Utf8.mk "true"))
377 in
378 let particle_node = find_particle derivation in
379 let content_type =
380 match derivation_type with
381 | `Restriction ->
382 (match particle_node with
383 | None -> CT_empty
384 | Some p_node ->
385 let particle = parse_particle resolver p_node in
386 CT_model (particle, mixed))
387 | `Extension ->
388 let base_ct = content_type_of_type !base in (* TODO BUG HERE if base =
389 AnyType *)
390 (match particle_node with
391 | None -> base_ct
392 | Some pnode ->
393 let particle = parse_particle resolver pnode in
394 (match base_ct with
395 | CT_empty -> CT_model (particle, mixed)
396 | CT_model (p, _) ->
397 let model = Sequence (p::[particle]) in
398 CT_model
399 ((Intervals.V.one, Some (Intervals.V.one), Model model,
400 first_of_model_group model),
401 mixed)
402 | CT_simple _ -> assert false))
403 in
404 complex name !base derivation_type uses content_type
405 else (* neither simpleContent nor complexContent *)
406 let base = anyType in
407 let uses = parse_attribute_uses resolver `Restriction base n in
408 let mixed =
409 _has_attribute "mixed" n && (_attribute "mixed" n = Utf8.mk "true")
410 in
411 let content_type =
412 match find_particle n with
413 | None -> CT_empty
414 | Some pnode ->
415 let particle = parse_particle resolver pnode in
416 CT_model (particle, mixed)
417 in
418 complex name anyType `Restriction uses content_type
419
420 and parse_elt_decl (resolver: resolver) n: element_declaration =
421 debug_print ~n "Schema_parser.parse_elt_decl";
422 resolver#see n;
423 if not (_has_attribute "name" n) then
424 raise (XSD_validation_error "missing element name");
425 let name = _attribute "name" n in
426 let type_def = find_element_type resolver n in
427 let value_constr = parse_elt_value_constraint type_def n in
428 element name (ref type_def) value_constr
429
430 (* look for a type definition, try "simpleType" child, try "complexType"
431 * child, try "type" attribute, return anyType *)
432 and find_element_type (resolver: resolver) n =
433 if _has_element "xsd:simpleType" n then
434 Simple (parse_simple_type resolver (_element "xsd:simpleType" n))
435 else if _has_element "xsd:complexType" n then
436 Complex (parse_complex_type resolver (_element "xsd:complexType" n))
437 else if _has_attribute "type" n then
438 !(resolver#resolve_typ ~now:true (_attribute "type" n))
439 else
440 anyType
441
442 and parse_particle (resolver: resolver) n =
443 debug_print ~n "Schema_parser.parse_particle";
444 let min, max = parse_min_max n in
445 match n#node_type with
446 | T_element "xsd:element" ->
447 let elt_decl, first =
448 if _has_attribute "ref" n then
449 let ref = _attribute "ref" n in
450 (resolver#resolve_elt ~now:false ref, [ Some ref ])
451 else (* no "ref" attribute *)
452 let decl = parse_elt_decl resolver n in
453 (ref decl, [ Some (name_of_element_declaration decl) ])
454 in
455 (min, max, Elt elt_decl, first)
456 | T_element "xsd:group" ->
457 let model_group =
458 snd (resolver#resolve_model_group (_attribute "ref" n))
459 in
460 (min, max, Model model_group, first_of_model_group model_group)
461 | T_element "xsd:all" | T_element "xsd:sequence" | T_element "xsd:choice" ->
462 let model_group = parse_model_group resolver n in
463 (min, max, Model model_group, first_of_model_group model_group)
464 | _ -> assert false
465
466 and parse_model_group (resolver: resolver) n =
467 debug_print ~n "Schema_parser.parse_model_group";
468 match n#node_type with
469 | T_element "xsd:all" ->
470 All (List.map (parse_particle resolver) (_elements "xsd:element" n))
471 | T_element "xsd:sequence" ->
472 Sequence (List.map (parse_particle resolver) (find_particles n))
473 | T_element "xsd:choice" ->
474 Choice (List.map (parse_particle resolver) (find_particles n))
475 | _ -> assert false
476
477 and parse_att_group (resolver: resolver) n =
478 debug_print ~n "Schema_parser.parse_att_group";
479 resolver#see n;
480 let name = _attribute "name" n in
481 let uses1 =
482 List.map (parse_attribute_use resolver) (_elements "xsd:attribute" n)
483 in
484 let uses2 =
485 List.concat (List.map (fun name -> snd (resolver#resolve_att_group name))
486 (List.map (_attribute "ref") (_elements "xsd:attributeGroup" n)))
487 in
488 name, (uses1 @ uses2)
489
490 let parse_model_group_def (resolver: resolver) n =
491 debug_print ~n "Schema_parser.parse_model_group_def";
492 resolver#see n;
493 let name = _attribute "name" n in
494 let model_group_node =
495 _element' ["xsd:all"; "xsd:choice"; "xsd:sequence"] n
496 in
497 let model_group = parse_model_group resolver model_group_node in
498 name, model_group
499
500 (** @param root schema document root node *)
501 class lazy_resolver =
502 let fake_type_def =
503 Complex (~-1, Some (Utf8.mk " FAKE TYP "), AnyType, `Restriction, [],
504 CT_empty)
505 in
506 let fake_elt_decl = ~-2, Utf8.mk " FAKE ELT ", ref fake_type_def, None in
507 let is_fake_type_def = (==) fake_type_def in
508 let is_fake_elt_decl = (==) fake_elt_decl in
509 let validation_error s = raise (XSD_validation_error s) in
510 let get_ns_prefix n =
511 match n#node_type with T_namespace p -> p | _ -> assert false
512 in
513 let (^^) x y = Utf8.concat x y in
514 fun root ->
515 object (self)
516
517 val typs: (Utf8.t, type_definition ref) Hashtbl.t =
518 Hashtbl.create 17
519 val attrs: (Utf8.t, attribute_declaration) Hashtbl.t =
520 Hashtbl.create 17
521 val elts: (Utf8.t, element_declaration ref) Hashtbl.t =
522 Hashtbl.create 17
523 val attr_groups: (Utf8.t, attribute_group_definition) Hashtbl.t =
524 Hashtbl.create 17
525 val model_groups: (Utf8.t, model_group_definition) Hashtbl.t =
526 Hashtbl.create 17
527
528 val mutable seen_nodes = NodeSet.empty
529
530 val mutable targetNamespace = None
531 val mutable targetNamespace_prefix = "0TARGET0"
532 val namespace_manager = new Pxp_dtd.namespace_manager
533 val orig_ns_prefixes = Hashtbl.create 17
534
535 initializer
536 Schema_builtin.iter_builtin (* register built-in types *)
537 (fun st_def ->
538 let type_def = Simple st_def in
539 let name = name_of_type_definition type_def in
540 Hashtbl.replace typs name (ref type_def));
541 Hashtbl.replace typs (Utf8.mk "xsd:anyType") (ref AnyType);
542 List.iter (* fill namespace manager *)
543 (fun (p, ns) ->
544 namespace_manager#add_namespace (Utf8.get_str p) (Utf8.get_str ns))
545 Schema_xml.schema_ns_prefixes;
546 List.iter
547 (fun n ->
548 let prefix = get_ns_prefix n in
549 let uri = n#data in
550 if prefix <> "" then begin
551 Hashtbl.add orig_ns_prefixes prefix uri;
552 ignore (namespace_manager#lookup_or_add_namespace prefix uri)
553 end)
554 root#namespace_info#declaration;
555 if _has_attribute "targetNamespace" root then begin
556 let ns = _attribute "targetNamespace" root in
557 targetNamespace <- Some ns;
558 targetNamespace_prefix <-
559 namespace_manager#lookup_or_add_namespace
560 targetNamespace_prefix (Utf8.get_str ns)
561 end;
562
563 (** schemas namespaces handling *)
564
565 method targetNamespace =
566 match targetNamespace with
567 | None -> Ns.empty
568 | Some s -> Ns.mk s
569
570 (* qualify names of entities before registering them with defined
571 * targetNamespace, if any *)
572 method private qualify_name name =
573 match targetNamespace with
574 | None -> name
575 | Some _ -> (Utf8.mk (targetNamespace_prefix ^ ":")) ^^ name
576
577 (* resolve user references using our namespace manager *)
578 method private fix_namespace s =
579 match Ns.split_qname s with
580 | "", base ->
581 (match targetNamespace with
582 | None -> base
583 | Some _ -> (Utf8.mk targetNamespace_prefix) ^^ (Utf8.mk ":") ^^ base)
584 | prefix, base ->
585 (try
586 let orig_uri = Hashtbl.find orig_ns_prefixes prefix in
587 let new_prefix = namespace_manager#get_normprefix orig_uri in
588 (Utf8.mk new_prefix) ^^ (Utf8.mk ":") ^^ base
589 with Not_found ->
590 validation_error ("Can't resolve: " ^ Utf8.get_str s))
591
592 (** seen nodes accounting *)
593
594 method already_seen n = NodeSet.mem n seen_nodes
595 method see (n: pxp_node) =
596 debug_print "lazy_resolver.see";
597 if NodeSet.mem n seen_nodes then
598 validation_error "Types/Elements loop";
599 seen_nodes <- NodeSet.add n seen_nodes
600
601 method private find_global_component tag_pred name =
602 let basename = snd (Ns.split_qname name) in
603 find (fun n -> match n#node_type with
604 | T_element tag when tag_pred tag ->
605 (_has_attribute "name" n) && (_attribute "name" n = basename)
606 | _ -> false) root
607
608 (** registration of global entities *)
609
610 method register_typ name def =
611 debug_print "lazy_resolver.register_typ";
612 let name = self#qualify_name name in
613 if (Hashtbl.mem typs name) &&
614 (not (is_fake_type_def !(Hashtbl.find typs name))) then
615 validation_error ("Redefinition of type: " ^ Utf8.get_str name);
616 debug_print (sprintf "Osv_parser: registering TYPE %s"
617 (Utf8.get_str name));
618 let type_def_ref = self#resolve_typ ~fix_ns:false ~now:false name in
619 type_def_ref := def
620
621 method register_elt name decl =
622 debug_print "lazy_resolver.register_elt";
623 let name = self#qualify_name name in
624 if (Hashtbl.mem elts name) &&
625 (not (is_fake_elt_decl !(Hashtbl.find elts name))) then
626 validation_error ("Redefinition of element: " ^ Utf8.get_str name);
627 debug_print (sprintf "Osv_parser: registering ELEMENT %s"
628 (Utf8.get_str name));
629 let elt_decl_ref = self#resolve_elt ~fix_ns:false ~now:false name in
630 elt_decl_ref := decl
631
632 method register_att name decl =
633 debug_print "lazy_resolver.register_att";
634 let name = self#qualify_name name in
635 if Hashtbl.mem attrs name then
636 validation_error ("Redefinition of attribute: " ^ Utf8.get_str name);
637 debug_print (sprintf "Osv_parser: registering ATTRIBUTE %s"
638 (Utf8.get_str name));
639 Hashtbl.replace attrs name decl
640
641 method register_att_group name def =
642 debug_print "lazy_resolver.register_att_group";
643 let name = self#qualify_name name in
644 if Hashtbl.mem attr_groups name then
645 validation_error ("Redefinition of attribute group: " ^
646 Utf8.get_str name);
647 debug_print (sprintf "Osv_parser: registering ATTRIBUTE GROUP %s"
648 (Utf8.get_str name));
649 Hashtbl.replace attr_groups name def
650
651 method register_model_group name def =
652 debug_print "lazy_resolver.register_model_group";
653 let name = self#qualify_name name in
654 if Hashtbl.mem model_groups name then
655 validation_error ("Redefinition of model group: " ^ Utf8.get_str name);
656 debug_print (sprintf "Osv_parser: registering MODEL GROUP %s"
657 (Utf8.get_str name));
658 Hashtbl.replace model_groups name def
659
660 (** entities lookup *)
661
662 method resolve_typ ?(fix_ns = true) ~now name =
663 debug_print "lazy_resolver.resolve_typ";
664 let name = if fix_ns then self#fix_namespace name else name in
665 try
666 Hashtbl.find typs name
667 with Not_found ->
668 let type_def =
669 if now then (* resolve now: look for global type definitions *)
670 let type_node =
671 try
672 self#find_global_component
673 (fun tag ->
674 (tag = "xsd:simpleType") || (tag = "xsd:complexType"))
675 name
676 with Not_found ->
677 validation_error ("Can't find definition of type: " ^
678 Utf8.get_str name)
679 in
680 if _tag_name type_node = Utf8.mk "xsd:simpleType" then
681 Simple (parse_simple_type (self :> resolver) type_node)
682 else (* _tag_name type_node = "xsd:complexType" *)
683 Complex (parse_complex_type (self :> resolver) type_node)
684 else (* resolve later: return a fake type ref *)
685 fake_type_def
686 in
687 let type_def_ref = ref type_def in
688 Hashtbl.replace typs name type_def_ref;
689 type_def_ref
690
691 method resolve_simple_typ ?(fix_ns = true) name =
692 match !(self#resolve_typ ~fix_ns ~now:true name) with
693 | AnyType -> Primitive (Utf8.mk "xsd:anySimpleType")
694 | Simple st -> st
695 | Complex _ -> assert false
696
697 method resolve_elt ?(fix_ns = true) ~now name =
698 debug_print "lazy_resolver.resolve_elt";
699 let name = if fix_ns then self#fix_namespace name else name in
700 try
701 Hashtbl.find elts name
702 with Not_found ->
703 let elt_decl =
704 if now then (* resolve now: look for global element declarations *)
705 let elt_node =
706 try
707 self#find_global_component ((=) "xsd:element") name
708 with Not_found ->
709 validation_error ("Can't find declaration of element: " ^
710 Utf8.get_str name)
711 in
712 parse_elt_decl (self :> resolver) elt_node
713 else (* resolve later: return a fake element declaration *)
714 fake_elt_decl
715 in
716 let elt_decl_ref = ref elt_decl in
717 Hashtbl.replace elts name elt_decl_ref;
718 elt_decl_ref
719
720 method resolve_att ?(fix_ns = true) name =
721 debug_print "lazy_resolver.resolve_att";
722 let name = if fix_ns then self#fix_namespace name else name in
723 try
724 Hashtbl.find attrs name
725 with Not_found ->
726 let node =
727 try
728 self#find_global_component ((=) "xsd:attribute") name
729 with Not_found ->
730 validation_error ("Can't find declaration of attribute: " ^
731 Utf8.get_str name)
732 in
733 let att_decl = parse_att_decl (self :> resolver) node in
734 Hashtbl.replace attrs name att_decl;
735 att_decl
736
737 method resolve_att_group ?(fix_ns = true) name =
738 debug_print "lazy_resolver.resolve_att_group";
739 let name = if fix_ns then self#fix_namespace name else name in
740 try
741 Hashtbl.find attr_groups name
742 with Not_found ->
743 let node =
744 try
745 self#find_global_component ((=) "xsd:attributeGroup") name
746 with Not_found ->
747 validation_error
748 ("Can't find definition of attribute group: " ^ Utf8.get_str name)
749 in
750 let att_group_decl = parse_att_group (self :> resolver) node in
751 Hashtbl.replace attr_groups name att_group_decl;
752 att_group_decl
753
754 method resolve_model_group ?(fix_ns = true) name =
755 debug_print "lazy_resolver.resolve_model_group";
756 let name = if fix_ns then self#fix_namespace name else name in
757 try
758 Hashtbl.find model_groups name
759 with Not_found ->
760 let node =
761 try
762 self#find_global_component ((=) "xsd:group") name
763 with Not_found ->
764 validation_error
765 ("Can't find definition of model group: " ^ Utf8.get_str name)
766 in
767 let model_group = parse_model_group_def (self :> resolver) node in
768 Hashtbl.replace model_groups name model_group;
769 model_group
770
771 (** acces to registered global entities *)
772
773 method elt_decls = hashtbl_values (hashtbl_deref elts)
774 method type_defs = hashtbl_values (hashtbl_deref typs)
775 method att_decls = hashtbl_values attrs
776 method att_groups = hashtbl_values attr_groups
777 method model_groups = hashtbl_values model_groups
778
779 end
780
781 (** {2 module's interface implementation} *)
782
783 let schema_of_node root =
784 let resolver = new lazy_resolver root in
785 let resolver' = (resolver :> resolver) in
786 root#iter_nodes (fun n ->
787 if not (resolver#already_seen n) then
788 match n#node_type with
789 | T_element "xsd:element" ->
790 let name = _attribute "name" n in
791 resolver#register_elt name (parse_elt_decl resolver' n)
792 | T_element "xsd:simpleType" ->
793 let name = _attribute "name" n in
794 resolver#register_typ name (Simple (parse_simple_type resolver' n))
795 | T_element "xsd:complexType" ->
796 let name = _attribute "name" n in
797 resolver#register_typ name (Complex (parse_complex_type resolver' n))
798 | T_element "xsd:attribute" ->
799 let name = _attribute "name" n in
800 resolver#register_att name (parse_att_decl resolver' n)
801 | T_element "xsd:attributeGroup" ->
802 let name = _attribute "name" n in
803 resolver#register_att_group name (parse_att_group resolver' n)
804 | T_element "xsd:group" ->
805 let name = _attribute "name" n in
806 resolver#register_model_group name (parse_model_group_def resolver' n)
807 | _ -> ());
808 {
809 targetNamespace = resolver#targetNamespace;
810 types = resolver#type_defs;
811 attributes = resolver#att_decls;
812 elements = resolver#elt_decls;
813 attribute_groups = resolver#att_groups;
814 model_groups = resolver#model_groups
815 }
816
817 let parse_schema source =
818 let config =
819 { new_xsd_config () with Pxp_types.enable_namespace_info = true }
820 in
821 let schema = schema_of_node (pxp_node_of ~config source) in
822 debug_print "parse_schema completed successfully";
823 schema
824
825 let schema_of_file fname = parse_schema (Pxp_types.from_file fname)
826
827 let schema_of_string s = parse_schema (Pxp_types.from_string s)
828
829

CVS Admin">CVS Admin
ViewVC Help
Powered by ViewVC 1.1.5