open Printf open Schema_types let no_facets = { length = None; minLength = None; maxLength = None; (* pattern = []; *) enumeration = None; whiteSpace = `Collapse, true; maxInclusive = None; maxExclusive = None; minInclusive = None; minExclusive = None; (* totalDigits = None; fractionDigits = None; *) } let name_of_element_declaration (_, name, _, _) = name let name_of_simple_type_definition = function | Primitive name -> name | Derived (Some name, _, _, _) -> name | _ -> raise (Invalid_argument "anonymous simple type definition") let name_of_complex_type_definition = function | _, Some name, _, _, _, _ -> name | _ -> raise (Invalid_argument "anonymous complex type definition") let name_of_type_definition = function | AnyType -> "xsd:anyType" | Simple st -> name_of_simple_type_definition st | Complex ct -> name_of_complex_type_definition ct let name_of_attribute_declaration (name, _, _) = name let name_of_attribute_use (_, (name, _, _), _) = name let variety_of_simple_type_definition = function | (Primitive name) as st -> Atomic st | Derived (_, variety, _, _) -> variety let simple_type_of_type = function | Simple s -> s | _ -> raise (Invalid_argument "simple_type_of_type") let complex_type_of_type = function | Complex c -> c | _ -> raise (Invalid_argument "complex_type_of_type") let content_type_of_type = function | AnyType -> assert false | Complex (_, _, _, _, _, ct) -> ct | Simple st -> CT_simple st let facets_of_simple_type_definition = function | Primitive _ -> no_facets | Derived (_, _, facets, _) -> facets let iter_types schema f = List.iter f schema.types let iter_attributes schema f = List.iter f schema.attributes let iter_elements schema f = List.iter f schema.elements let iter_attribute_groups schema f = List.iter f schema.attribute_groups let iter_model_groups schema f = List.iter f schema.model_groups exception XSD_validation_error of string exception XSI_validation_error of string let regexp' s = Pcre.regexp ~flags:[`UTF8] s let rec normalize_white_space = let ws_RE = regexp' "[\t\r\n]" in let spaces_RE = regexp' "[ ]+" in let margins_RE = regexp' "^ (.*) $" in fun handling s -> match handling with | `Preserve -> s | `Replace -> Pcre.replace ~rex:ws_RE ~templ:" " s | `Collapse -> let s' = Pcre.replace ~rex:spaces_RE ~templ:" " (normalize_white_space `Replace s) in Pcre.replace ~rex:margins_RE ~templ:"$1" s' let anySimpleType = Primitive "xsd:anySimpleType" let anyType = AnyType let get_interval facets = (* ASSUMPTION: * not (facets.minInclusive = Some _ && facets.minExclusive = Some _) * not (facets.maxInclusive = Some _ && facets.maxExclusive = Some _) * Value.t is an integer! (no other intervals are actually supported * by the CDuce type system) *) let min = match facets.minInclusive, facets.minExclusive with | Some (Value.Integer i, _), None -> Some i | None, Some (Value.Integer i, _) -> Some (Intervals.V.succ i) | None, None -> None | _ -> assert false in let max = match facets.maxInclusive, facets.maxExclusive with | Some (Value.Integer i, _), None -> Some i | None, Some (Value.Integer i, _) -> Some (Intervals.V.pred i) | None, None -> None | _ -> assert false in match min, max with | Some min, Some max -> Intervals.bounded min max | Some min, None -> Intervals.right min | None, Some max -> Intervals.left max | None, None -> Intervals.any let print_simple_type fmt = function | Primitive name -> Format.fprintf fmt "%s" name | Derived (Some name, _, _, _) -> Format.fprintf fmt "%s'" name | Derived (None, _, _, _) -> Format.fprintf fmt "unnamed'" let print_complex_type fmt = function | (id, Some name, _, _, _, _) -> Format.fprintf fmt "%d:%s" id name | (id, None, _, _, _, _) -> Format.fprintf fmt "%d:unnamed'" id let print_type fmt = function | AnyType -> Format.fprintf fmt "xsd:anyType" | Simple t -> Format.fprintf fmt "S:%a" print_simple_type t | Complex t -> Format.fprintf fmt "C:%a" print_complex_type t let print_attribute fmt (name, t, _) = Format.fprintf fmt "@@%s:%a" name print_simple_type t let print_element fmt (id, name, _, _) = Format.fprintf fmt "E:%d:<%s>" id name let print_attributes fmt = List.iter (Format.fprintf fmt "%a" print_attribute) let print_attribute_group fmt (name, _) = Format.fprintf fmt "{agroup:%s}" name let print_model_group fmt (name, _) = Format.fprintf fmt "{mgroup:%s}" name let print_schema fmt schema = let defined_types = (* filter out built-in types *) List.filter (fun def -> not (Schema_xml.has_xsd_prefix (name_of_type_definition def))) schema.types in if defined_types <> [] then begin Format.fprintf fmt "Types: "; List.iter (fun c -> print_type fmt c; Format.fprintf fmt " ") defined_types; Format.fprintf fmt "\n" end; if schema.attributes <> [] then begin Format.fprintf fmt "Attributes: "; List.iter (fun c -> print_attribute fmt c; Format.fprintf fmt " ") schema.attributes; Format.fprintf fmt "\n" end; if schema.elements <> [] then begin Format.fprintf fmt "Elements: "; List.iter (fun c -> print_element fmt c; Format.fprintf fmt " ") schema.elements; Format.fprintf fmt "\n" end; if schema.attribute_groups <> [] then begin Format.fprintf fmt "Attribute groups: "; List.iter (fun c -> print_attribute_group fmt c; Format.fprintf fmt " ") schema.attribute_groups; Format.fprintf fmt "\n" end; if schema.model_groups <> [] then begin Format.fprintf fmt "Model groups: "; List.iter (fun c -> print_model_group fmt c; Format.fprintf fmt " ") schema.model_groups; Format.fprintf fmt "\n" end (** naive implementation: doesn't follow XML Schema constraints on facets * merging. Here all new facets override old ones *) let merge_facets old_facets new_facets = let maxInclusive, maxExclusive = match new_facets.maxInclusive, new_facets.maxExclusive with | None, None -> old_facets.maxInclusive, old_facets.maxExclusive | Some _, Some _ -> assert false | v -> v in let minInclusive, minExclusive = match new_facets.minInclusive, new_facets.minExclusive with | None, None -> old_facets.minInclusive, old_facets.minExclusive | Some _, Some _ -> assert false | v -> v in { old_facets with length = (match new_facets.length with | None -> old_facets.length | v -> v); minLength = (match new_facets.minLength with | None -> old_facets.minLength | v -> v); maxLength = (match new_facets.maxLength with | None -> old_facets.maxLength | v -> v); enumeration = (match new_facets.enumeration with | None -> old_facets.enumeration | v -> v); whiteSpace = new_facets.whiteSpace; maxInclusive = maxInclusive; maxExclusive = maxExclusive; minInclusive = minInclusive; minExclusive = minExclusive; } let restrict base new_facets new_name = let variety = variety_of_simple_type_definition base in let facets = merge_facets (facets_of_simple_type_definition base) new_facets in Derived (new_name, variety, facets, base)