Laurent@814: #!/usr/bin/env python
Laurent@814: # -*- coding: utf-8 -*-
Laurent@814: 
Laurent@814: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
Laurent@814: #based on the plcopen standard. 
Laurent@814: #
Laurent@814: #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
Laurent@814: #
Laurent@814: #See COPYING file for copyrights details.
Laurent@814: #
Laurent@814: #This library is free software; you can redistribute it and/or
Laurent@814: #modify it under the terms of the GNU General Public
Laurent@814: #License as published by the Free Software Foundation; either
Laurent@814: #version 2.1 of the License, or (at your option) any later version.
Laurent@814: #
Laurent@814: #This library is distributed in the hope that it will be useful,
Laurent@814: #but WITHOUT ANY WARRANTY; without even the implied warranty of
Laurent@814: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Laurent@814: #General Public License for more details.
Laurent@814: #
Laurent@814: #You should have received a copy of the GNU General Public
Laurent@814: #License along with this library; if not, write to the Free Software
Laurent@814: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Laurent@814: 
Laurent@814: import os, re
Laurent@814: import datetime
Laurent@814: from xml.dom import minidom
Laurent@814: from types import *
Laurent@814: 
Laurent@814: from xmlclass import *
Laurent@814: 
Laurent@814: def GenerateDictFacets(facets):
Laurent@814:     return dict([(name, (None, False)) for name in facets])
Laurent@814: 
Laurent@814: def GenerateSimpleTypeXMLText(function):
Laurent@814:     def generateXMLTextMethod(value, name=None, indent=0):
Laurent@814:         text = ""
Laurent@814:         if name is not None:
Laurent@814:             ind1, ind2 = getIndent(indent, name)
Laurent@814:             text += ind1 + "<%s>" % name
Laurent@814:         text += function(value)
Laurent@814:         if name is not None:
Laurent@814:             text += "</%s>\n" % name
Laurent@814:         return text
Laurent@814:     return generateXMLTextMethod
Laurent@814: 
Laurent@1373: def GenerateFloatXMLText(extra_values=[], decimal=None):
Laurent@1374:     float_format = (lambda x: "{:.{width}f}".format(x, width=decimal).rstrip('0')
Laurent@1374:                     if decimal is not None else str)
Laurent@814:     def generateXMLTextMethod(value, name=None, indent=0):
Laurent@814:         text = ""
Laurent@814:         if name is not None:
Laurent@814:             ind1, ind2 = getIndent(indent, name)
Laurent@814:             text += ind1 + "<%s>" % name
Laurent@1375:         if isinstance(value, IntType):
Laurent@1375:             text += str(value)
Laurent@1375:         elif value in extra_values or value % 1 != 0:
Laurent@1373:             text += float_format(value)
Laurent@814:         else:
Laurent@1375:             text += "{:.0f}".format(value)
Laurent@814:         if name is not None:
Laurent@814:             text += "</%s>\n" % name
Laurent@814:         return text
Laurent@814:     return generateXMLTextMethod
Laurent@814:         
Laurent@814: DEFAULT_FACETS = GenerateDictFacets(["pattern", "whiteSpace", "enumeration"])
Laurent@814: NUMBER_FACETS = GenerateDictFacets(DEFAULT_FACETS.keys() + ["maxInclusive", "maxExclusive", "minInclusive", "minExclusive"])
Laurent@814: DECIMAL_FACETS = GenerateDictFacets(NUMBER_FACETS.keys() + ["totalDigits", "fractionDigits"])
Laurent@814: STRING_FACETS = GenerateDictFacets(DEFAULT_FACETS.keys() + ["length", "minLength", "maxLength"])
Laurent@814: 
Laurent@814: ALL_FACETS = ["pattern", "whiteSpace", "enumeration", "maxInclusive", 
Laurent@814:     "maxExclusive", "minInclusive", "minExclusive", "totalDigits", 
Laurent@814:     "fractionDigits", "length", "minLength", "maxLength"]
Laurent@814: 
Laurent@814: 
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: #                           Structure reducing functions
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: 
Laurent@814: 
Laurent@814: # Documentation elements
Laurent@814: 
Laurent@814: def ReduceAppInfo(factory, attributes, elements):
Laurent@814:     return {"type": "appinfo", "source": attributes.get("source", None), 
Laurent@814:             "content": "\n".join(elements)}
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceDocumentation(factory, attributes, elements):
Laurent@814:     return {"type": "documentation", "source": attributes.get("source", None), 
Laurent@814:             "language": attributes.get("lang", "any"), "content": "\n".join(elements)}
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceAnnotation(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     annotation = {"type": "annotation", "appinfo": [], "documentation": {}}
Laurent@814:     for child in children:
Laurent@814:         if child["type"] == "appinfo":
Laurent@814:             annotation["appinfo"].append((child["source"], child["content"]))
Laurent@814:         elif child["type"] == "documentation":
Laurent@814:             if child["source"] is not None:
Laurent@814:                 text = "(source: %(source)s):\n%(content)s\n\n"%child
Laurent@814:             else:
Laurent@814:                 text = child["content"] + "\n\n"
Laurent@814:             if not annotation["documentation"].has_key(child["language"]):
Laurent@814:                 annotation["documentation"] = text
Laurent@814:             else:
Laurent@814:                 annotation["documentation"] += text
Laurent@814:     return annotation
Laurent@814: 
Laurent@814: # Simple type elements
Laurent@814: 
Laurent@814: def GenerateFacetReducing(facetname, canbefixed):
Laurent@814:     def ReduceFacet(factory, attributes, elements):
Laurent@814:         annotations, children = factory.ReduceElements(elements)
Laurent@814:         if attributes.has_key("value"):
Laurent@814:             facet = {"type": facetname, "value": attributes["value"], "doc": annotations}
Laurent@814:             if canbefixed:
Laurent@814:                 facet["fixed"] = attributes.get("fixed", False)
Laurent@814:             return facet
Laurent@814:         raise ValueError("A value must be defined for the \"%s\" facet!" % facetname)
Laurent@814:     return ReduceFacet
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceList(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     list = {"type": "list", "itemType": attributes.get("itemType", None), "doc": annotations}
Laurent@814:     
Laurent@814:     if len(children) > 0 and children[0]["type"] == SIMPLETYPE:
Laurent@814:         if list["itemType"] is None:
Laurent@814:             list["itemType"] = children[0]
Laurent@814:         else:
Laurent@814:             raise ValueError("Only one base type can be defined for restriction!")
Laurent@814:     if list["itemType"] is None:
Laurent@814:         raise ValueError("No base type has been defined for list!")
Laurent@814:     return list
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceUnion(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     union = {"type": "union", "memberTypes": attributes.get("memberTypes", []), "doc": annotations}
Laurent@814:     
Laurent@814:     for child in children:
Laurent@814:         if child["type"] == SIMPLETYPE:
Laurent@814:             union["memberTypes"].appendchild
Laurent@814:     if len(union["memberTypes"]) == 0:
Laurent@814:         raise ValueError("No base type has been defined for union!")
Laurent@814:     return union
Laurent@814: 
Laurent@814: 
Laurent@814: def CreateSimpleType(factory, attributes, typeinfos):
Laurent@814:     # Initialize type informations
Laurent@814:     facets = {}
Laurent@814:     simpleType = {"type": SIMPLETYPE, "final": attributes.get("final", [])}
Laurent@814:     if attributes.has_key("name"):
Laurent@814:         simpleType["name"] = attributes["name"]
Laurent@814:     
Laurent@814:     if typeinfos["type"] in ["restriction", "extension"]:
Laurent@814:         # Search for base type definition
Laurent@814:         if isinstance(typeinfos["base"], (StringType, UnicodeType)):
Laurent@814:             basetypeinfos = factory.FindSchemaElement(typeinfos["base"], SIMPLETYPE)
Laurent@814:             if basetypeinfos is None:
Laurent@814:                 raise "\"%s\" isn't defined!" % typeinfos["base"] 
Laurent@814:         else:
Laurent@814:             basetypeinfos = typeinfos["base"]
Laurent@814:         
Laurent@814:         # Check that base type is a simple type
Laurent@814:         if basetypeinfos["type"] != SIMPLETYPE:
Laurent@814:             raise ValueError("Base type given isn't a simpleType!")
Laurent@814:         
Laurent@814:         simpleType["basename"] = basetypeinfos["basename"]
Laurent@814:         
Laurent@814:         # Check that derivation is allowed
Laurent@814:         if basetypeinfos.has_key("final"):
Laurent@814:             if "#all" in basetypeinfos["final"]:
Laurent@814:                 raise ValueError("Base type can't be derivated!")
Laurent@814:             if "restriction" in basetypeinfos["final"] and typeinfos["type"] == "restriction":
Laurent@814:                 raise ValueError("Base type can't be derivated by restriction!")
Laurent@814:         
Laurent@814:         # Extract simple type facets
Laurent@814:         for facet in typeinfos.get("facets", []):
Laurent@814:             facettype = facet["type"]
Laurent@814:             if not basetypeinfos["facets"].has_key(facettype):
Laurent@814:                 raise ValueError("\"%s\" facet can't be defined for \"%s\" type!" % (facettype, type))
Laurent@814:             elif basetypeinfos["facets"][facettype][1]:
Laurent@814:                 raise ValueError("\"%s\" facet is fixed on base type!" % facettype)
Laurent@814:             value = facet["value"]
Laurent@814:             basevalue = basetypeinfos["facets"][facettype][0]
Laurent@814:             if facettype in ["enumeration", "pattern"]:
Laurent@814:                 value = basetypeinfos["extract"](value, False)
Laurent@814:                 if len(facets) == 0:
Laurent@814:                     facets[facettype] = ([value], False)
Laurent@814:                     continue
Laurent@814:                 elif facets.keys() == [facettype]:
Laurent@814:                     facets[facettype][0].append(value)
Laurent@814:                     continue
Laurent@814:                 else:
Laurent@814:                     raise ValueError("\"%s\" facet can't be defined with another facet type!" % facettype)
Laurent@814:             elif facets.has_key("enumeration"):
Laurent@814:                 raise ValueError("\"enumeration\" facet can't be defined with another facet type!")
Laurent@814:             elif facets.has_key("pattern"):
Laurent@814:                 raise ValueError("\"pattern\" facet can't be defined with another facet type!")
Laurent@814:             elif facets.has_key(facettype):
Laurent@814:                 raise ValueError("\"%s\" facet can't be defined two times!" % facettype)
Laurent@814:             elif facettype == "length":
Laurent@814:                 if facets.has_key("minLength"):
Laurent@814:                     raise ValueError("\"length\" and \"minLength\" facets can't be defined at the same time!")
Laurent@814:                 if facets.has_key("maxLength"):
Laurent@814:                     raise ValueError("\"length\" and \"maxLength\" facets can't be defined at the same time!")
Laurent@814:                 try:
Laurent@814:                     value = int(value)
Laurent@814:                 except:
Laurent@814:                     raise ValueError("\"length\" must be an integer!")
Laurent@814:                 if value < 0:
Laurent@814:                     raise ValueError("\"length\" can't be negative!")
Laurent@814:                 elif basevalue is not None and basevalue != value:
Laurent@814:                     raise ValueError("\"length\" can't be different from \"length\" defined in base type!")
Laurent@814:             elif facettype == "minLength":
Laurent@814:                 if facets.has_key("length"):
Laurent@814:                     raise ValueError("\"length\" and \"minLength\" facets can't be defined at the same time!")
Laurent@814:                 try:
Laurent@814:                     value = int(value)
Laurent@814:                 except:
Laurent@814:                     raise ValueError("\"minLength\" must be an integer!")
Laurent@814:                 if value < 0:
Laurent@814:                     raise ValueError("\"minLength\" can't be negative!")
Laurent@814:                 elif facets.has_key("maxLength") and value > facets["maxLength"]:
Laurent@814:                     raise ValueError("\"minLength\" must be lesser than or equal to \"maxLength\"!")
Laurent@814:                 elif basevalue is not None and basevalue < value:
Laurent@814:                     raise ValueError("\"minLength\" can't be lesser than \"minLength\" defined in base type!")
Laurent@814:             elif facettype == "maxLength":
Laurent@814:                 if facets.has_key("length"):
Laurent@814:                     raise ValueError("\"length\" and \"maxLength\" facets can't be defined at the same time!")
Laurent@814:                 try:
Laurent@814:                     value = int(value)
Laurent@814:                 except:
Laurent@814:                     raise ValueError("\"maxLength\" must be an integer!")
Laurent@814:                 if value < 0:
Laurent@814:                     raise ValueError("\"maxLength\" can't be negative!")
Laurent@814:                 elif facets.has_key("minLength") and value < facets["minLength"]:
Laurent@814:                     raise ValueError("\"minLength\" must be lesser than or equal to \"maxLength\"!")
Laurent@814:                 elif basevalue is not None and basevalue > value:
Laurent@814:                     raise ValueError("\"maxLength\" can't be greater than \"maxLength\" defined in base type!")
Laurent@814:             elif facettype == "minInclusive":
Laurent@814:                 if facets.has_key("minExclusive"):
Laurent@814:                     raise ValueError("\"minExclusive\" and \"minInclusive\" facets can't be defined at the same time!")
Laurent@814:                 value = basetypeinfos["extract"](facet["value"], False)
Laurent@814:                 if facets.has_key("maxInclusive") and value > facets["maxInclusive"][0]:
Laurent@814:                     raise ValueError("\"minInclusive\" must be lesser than or equal to \"maxInclusive\"!")
Laurent@814:                 elif facets.has_key("maxExclusive") and value >= facets["maxExclusive"][0]:
Laurent@814:                     raise ValueError("\"minInclusive\" must be lesser than \"maxExclusive\"!")
Laurent@814:             elif facettype == "minExclusive":
Laurent@814:                 if facets.has_key("minInclusive"):
Laurent@814:                     raise ValueError("\"minExclusive\" and \"minInclusive\" facets can't be defined at the same time!")
Laurent@814:                 value = basetypeinfos["extract"](facet["value"], False)
Laurent@814:                 if facets.has_key("maxInclusive") and value >= facets["maxInclusive"][0]:
Laurent@814:                     raise ValueError("\"minExclusive\" must be lesser than \"maxInclusive\"!")
Laurent@814:                 elif facets.has_key("maxExclusive") and value >= facets["maxExclusive"][0]:
Laurent@814:                     raise ValueError("\"minExclusive\" must be lesser than \"maxExclusive\"!")
Laurent@814:             elif facettype == "maxInclusive":
Laurent@814:                 if facets.has_key("maxExclusive"):
Laurent@814:                     raise ValueError("\"maxExclusive\" and \"maxInclusive\" facets can't be defined at the same time!")
Laurent@814:                 value = basetypeinfos["extract"](facet["value"], False)
Laurent@814:                 if facets.has_key("minInclusive") and value < facets["minInclusive"][0]:
Laurent@814:                     raise ValueError("\"minInclusive\" must be lesser than or equal to \"maxInclusive\"!")
Laurent@814:                 elif facets.has_key("minExclusive") and value <= facets["minExclusive"][0]:
Laurent@814:                     raise ValueError("\"minExclusive\" must be lesser than \"maxInclusive\"!")
Laurent@814:             elif facettype == "maxExclusive":
Laurent@814:                 if facets.has_key("maxInclusive"):
Laurent@814:                     raise ValueError("\"maxExclusive\" and \"maxInclusive\" facets can't be defined at the same time!")
Laurent@814:                 value = basetypeinfos["extract"](facet["value"], False)
Laurent@814:                 if facets.has_key("minInclusive") and value <= facets["minInclusive"][0]:
Laurent@814:                     raise ValueError("\"minInclusive\" must be lesser than \"maxExclusive\"!")
Laurent@814:                 elif facets.has_key("minExclusive") and value <= facets["minExclusive"][0]:
Laurent@814:                     raise ValueError("\"minExclusive\" must be lesser than \"maxExclusive\"!")
Laurent@814:             elif facettype == "whiteSpace":
Laurent@814:                 if basevalue == "collapse" and value in ["preserve", "replace"] or basevalue == "replace" and value == "preserve":
Laurent@814:                    raise ValueError("\"whiteSpace\" is incompatible with \"whiteSpace\" defined in base type!")
Laurent@814:             elif facettype == "totalDigits":
Laurent@814:                 if facets.has_key("fractionDigits") and value <= facets["fractionDigits"][0]:
Laurent@814:                     raise ValueError("\"fractionDigits\" must be lesser than or equal to \"totalDigits\"!")
Laurent@814:                 elif basevalue is not None and value > basevalue:
Laurent@814:                     raise ValueError("\"totalDigits\" can't be greater than \"totalDigits\" defined in base type!")
Laurent@814:             elif facettype == "fractionDigits":
Laurent@814:                 if facets.has_key("totalDigits") and value <= facets["totalDigits"][0]:
Laurent@814:                     raise ValueError("\"fractionDigits\" must be lesser than or equal to \"totalDigits\"!")
Laurent@814:                 elif basevalue is not None and value > basevalue:
Laurent@814:                     raise ValueError("\"totalDigits\" can't be greater than \"totalDigits\" defined in base type!")
Laurent@814:             facets[facettype] = (value, facet.get("fixed", False))
Laurent@814:         
Laurent@814:         # Report not redefined facet from base type to new created type 
Laurent@814:         for facettype, facetvalue in basetypeinfos["facets"].items():
Laurent@814:             if not facets.has_key(facettype):
Laurent@814:                 facets[facettype] = facetvalue
Laurent@814:         
Laurent@814:         # Generate extract value for new created type
Laurent@814:         def ExtractSimpleTypeValue(attr, extract=True):
Laurent@814:             value = basetypeinfos["extract"](attr, extract)
Laurent@814:             for facetname, (facetvalue, facetfixed) in facets.items():
Laurent@814:                 if facetvalue is not None:
Laurent@814:                     if facetname == "enumeration" and value not in facetvalue:
Laurent@814:                         raise ValueError("\"%s\" not in enumerated values" % value)
Laurent@814:                     elif facetname == "length" and len(value) != facetvalue:
Laurent@814:                         raise ValueError("value must have a length of %d" % facetvalue)
Laurent@814:                     elif facetname == "minLength" and len(value) < facetvalue:
Laurent@814:                         raise ValueError("value must have a length of %d at least" % facetvalue)
Laurent@814:                     elif facetname == "maxLength" and len(value) > facetvalue:
Laurent@814:                         raise ValueError("value must have a length of %d at most" % facetvalue)
Laurent@814:                     elif facetname == "minInclusive" and value < facetvalue:
Laurent@814:                         raise ValueError("value must be greater than or equal to %s" % str(facetvalue))
Laurent@814:                     elif facetname == "minExclusive" and value <= facetvalue:
Laurent@814:                         raise ValueError("value must be greater than %s" % str(facetvalue))
Laurent@814:                     elif facetname == "maxInclusive" and value > facetvalue:
Laurent@814:                         raise ValueError("value must be lesser than or equal to %s" % str(facetvalue))
Laurent@814:                     elif facetname == "maxExclusive"  and value >= facetvalue:
Laurent@814:                         raise ValueError("value must be lesser than %s" % str(facetvalue))
Laurent@814:                     elif facetname == "pattern":
Laurent@814:                         model = re.compile("(?:%s)?$" % "|".join(map(lambda x: "(?:%s)" % x, facetvalue)))
Laurent@814:                         result = model.match(value)
Laurent@814:                         if result is None:
Laurent@814:                             if len(facetvalue) > 1:   
Laurent@814:                                 raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue))
Laurent@814:                             else:
Laurent@814:                                 raise ValueError("value doesn't follow the pattern %s" % facetvalue[0])
Laurent@814:                     elif facetname == "whiteSpace":
Laurent@814:                         if facetvalue == "replace":
Laurent@814:                             value = GetNormalizedString(value, False)
Laurent@814:                         elif facetvalue == "collapse":
Laurent@814:                             value = GetToken(value, False)
Laurent@814:             return value
Laurent@814:         
Laurent@814:         def CheckSimpleTypeValue(value):
Laurent@814:             for facetname, (facetvalue, facetfixed) in facets.items():
Laurent@814:                 if facetvalue is not None:
Laurent@814:                     if facetname == "enumeration" and value not in facetvalue:
Laurent@814:                         return False
Laurent@814:                     elif facetname == "length" and len(value) != facetvalue:
Laurent@814:                         return False
Laurent@814:                     elif facetname == "minLength" and len(value) < facetvalue:
Laurent@814:                         return False
Laurent@814:                     elif facetname == "maxLength" and len(value) > facetvalue:
Laurent@814:                         return False
Laurent@814:                     elif facetname == "minInclusive" and value < facetvalue:
Laurent@814:                         return False
Laurent@814:                     elif facetname == "minExclusive" and value <= facetvalue:
Laurent@814:                         return False
Laurent@814:                     elif facetname == "maxInclusive" and value > facetvalue:
Laurent@814:                         return False
Laurent@814:                     elif facetname == "maxExclusive"  and value >= facetvalue:
Laurent@814:                         return False
Laurent@814:                     elif facetname == "pattern":
Laurent@814:                         model = re.compile("(?:%s)?$" % "|".join(map(lambda x: "(?:%s)" % x, facetvalue)))
Laurent@814:                         result = model.match(value)
Laurent@814:                         if result is None:
Laurent@814:                             if len(facetvalue) > 1:   
Laurent@814:                                 raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue))
Laurent@814:                             else:
Laurent@814:                                 raise ValueError("value doesn't follow the pattern %s" % facetvalue[0])
Laurent@814:             return True
Laurent@814:         
Laurent@814:         def SimpleTypeInitialValue():
Laurent@814:             for facetname, (facetvalue, facetfixed) in facets.items():
Laurent@814:                 if facetvalue is not None:
Laurent@814:                     if facetname == "enumeration":
Laurent@814:                         return facetvalue[0]
Laurent@814:                     elif facetname == "length":
Laurent@814:                         return " "*facetvalue
Laurent@814:                     elif facetname == "minLength":
Laurent@814:                         return " "*minLength
Laurent@814:                     elif facetname == "minInclusive" and facetvalue > 0:
Laurent@814:                         return facetvalue
Laurent@814:                     elif facetname == "minExclusive" and facetvalue >= 0:
Laurent@814:                         return facetvalue + 1
Laurent@814:                     elif facetname == "maxInclusive" and facetvalue < 0:
Laurent@814:                         return facetvalue
Laurent@814:                     elif facetname == "maxExclusive"  and facetvalue <= 0:
Laurent@814:                         return facetvalue - 1
Laurent@814:             return basetypeinfos["initial"]()
Laurent@814:         
Laurent@814:         GenerateSimpleType = basetypeinfos["generate"]
Laurent@814:         
Laurent@814:     elif typeinfos["type"] == "list":
Laurent@814:         # Search for item type definition
Laurent@814:         if isinstance(typeinfos["itemType"], (StringType, UnicodeType)):
Laurent@814:             itemtypeinfos = factory.FindSchemaElement(typeinfos["itemType"], SIMPLETYPE)
Laurent@814:             if itemtypeinfos is None:
Laurent@814:                 raise "\"%s\" isn't defined!" % typeinfos["itemType"]
Laurent@814:         else:
Laurent@814:             itemtypeinfos = typeinfos["itemType"]
Laurent@814:         
Laurent@814:         # Check that item type is a simple type
Laurent@814:         if itemtypeinfos["type"] != SIMPLETYPE:
Laurent@814:             raise ValueError, "Item type given isn't a simpleType!"
Laurent@814:         
Laurent@814:         simpleType["basename"] = "list"
Laurent@814:         
Laurent@814:         # Check that derivation is allowed
Laurent@814:         if itemtypeinfos.has_key("final"):
Laurent@814:             if itemtypeinfos["final"].has_key("#all"):
Laurent@814:                 raise ValueError("Item type can't be derivated!")
Laurent@814:             if itemtypeinfos["final"].has_key("list"):
Laurent@814:                 raise ValueError("Item type can't be derivated by list!")
Laurent@814:         
Laurent@814:         # Generate extract value for new created type
Laurent@814:         def ExtractSimpleTypeValue(attr, extract = True):
Laurent@814:             values = []
Laurent@814:             for value in GetToken(attr, extract).split(" "):
Laurent@814:                 values.append(itemtypeinfos["extract"](value, False))
Laurent@814:             return values
Laurent@814:         
Laurent@814:         def CheckSimpleTypeValue(value):
Laurent@814:             for item in value:
Laurent@814:                 result = itemtypeinfos["check"](item)
Laurent@814:                 if not result:
Laurent@814:                     return result
Laurent@814:             return True
Laurent@814:         
Laurent@814:         SimpleTypeInitialValue = lambda: []
Laurent@814:         
Laurent@814:         GenerateSimpleType = GenerateSimpleTypeXMLText(lambda x: " ".join(map(itemtypeinfos["generate"], x)))
Laurent@814:         
Laurent@814:         facets = GenerateDictFacets(["length", "maxLength", "minLength", "enumeration", "pattern"])
Laurent@814:         facets["whiteSpace"] = ("collapse", False)
Laurent@814:     
Laurent@814:     elif typeinfos["type"] == "union":
Laurent@814:         # Search for member types definition
Laurent@814:         membertypesinfos = []
Laurent@814:         for membertype in typeinfos["memberTypes"]:
Laurent@814:             if isinstance(membertype, (StringType, UnicodeType)):
Laurent@814:                 infos = factory.FindSchemaElement(membertype, SIMPLETYPE)
Laurent@814:                 if infos is None:
Laurent@814:                     raise ValueError("\"%s\" isn't defined!" % membertype)
Laurent@814:             else:
Laurent@814:                 infos = membertype
Laurent@814:             
Laurent@814:             # Check that member type is a simple type
Laurent@814:             if infos["type"] != SIMPLETYPE:
Laurent@814:                 raise ValueError("Member type given isn't a simpleType!")
Laurent@814:             
Laurent@814:             # Check that derivation is allowed
Laurent@814:             if infos.has_key("final"):
Laurent@814:                 if infos["final"].has_key("#all"):
Laurent@814:                     raise ValueError("Item type can't be derivated!")
Laurent@814:                 if infos["final"].has_key("union"):
Laurent@814:                     raise ValueError("Member type can't be derivated by union!")
Laurent@814:             
Laurent@814:             membertypesinfos.append(infos)
Laurent@814:         
Laurent@814:         simpleType["basename"] = "union"
Laurent@814:         
Laurent@814:         # Generate extract value for new created type
Laurent@814:         def ExtractSimpleTypeValue(attr, extract = True):
Laurent@814:             if extract:
Laurent@814:                 value = GetAttributeValue(attr)
Laurent@814:             else:
Laurent@814:                 value = attr
Laurent@814:             for infos in membertypesinfos:
Laurent@814:                 try:
Laurent@814:                     return infos["extract"](attr, False)
Laurent@814:                 except:
Laurent@814:                     pass
Laurent@814:             raise ValueError("\"%s\" isn't valid for type defined for union!")
Laurent@814:         
Laurent@814:         def CheckSimpleTypeValue(value):
Laurent@814:             for infos in membertypesinfos:
Laurent@814:                 result = infos["check"](value)
Laurent@814:                 if result:
Laurent@814:                     return result
Laurent@814:             return False
Laurent@814:         
Laurent@814:         SimpleTypeInitialValue = membertypesinfos[0]["initial"]
Laurent@814:         
Laurent@814:         def GenerateSimpleTypeFunction(value):
Laurent@814:             if isinstance(value, BooleanType):
Laurent@814:                 return {True: "true", False: "false"}[value]
Laurent@814:             else:
Laurent@814:                 return str(value)
Laurent@814:         GenerateSimpleType = GenerateSimpleTypeXMLText(GenerateSimpleTypeFunction)
Laurent@814:         
Laurent@814:         facets = GenerateDictFacets(["pattern", "enumeration"])
Laurent@814:     
Laurent@814:     simpleType["facets"] = facets
Laurent@814:     simpleType["extract"] = ExtractSimpleTypeValue
Laurent@814:     simpleType["initial"] = SimpleTypeInitialValue
Laurent@814:     simpleType["check"] = CheckSimpleTypeValue
Laurent@814:     simpleType["generate"] = GenerateSimpleType
Laurent@814:     return simpleType
Laurent@814: 
Laurent@814: def ReduceSimpleType(factory, attributes, elements):
Laurent@814:     # Reduce all the simple type children
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     simpleType = CreateSimpleType(factory, attributes, children[0])
Laurent@814:     simpleType["doc"] = annotations
Laurent@814:     
Laurent@814:     return simpleType
Laurent@814: 
Laurent@814: # Complex type
Laurent@814: 
Laurent@814: def ExtractAttributes(factory, elements, base=None):
Laurent@814:     attrs = []
Laurent@814:     attrnames = {}
Laurent@814:     if base is not None:
Laurent@814:         basetypeinfos = factory.FindSchemaElement(base)
Laurent@814:         if not isinstance(basetypeinfos, (UnicodeType, StringType)) and basetypeinfos["type"] == COMPLEXTYPE:
Laurent@814:             attrnames = dict(map(lambda x:(x["name"], True), basetypeinfos["attributes"]))
Laurent@814:         
Laurent@814:     for element in elements:
Laurent@814:         if element["type"] == ATTRIBUTE:
Laurent@814:             if attrnames.get(element["name"], False):
Laurent@814:                 raise ValueError("\"%s\" attribute has been defined two times!" % element["name"])
Laurent@814:             else:
Laurent@814:                 attrnames[element["name"]] = True
Laurent@814:                 attrs.append(element)
Laurent@814:         elif element["type"] == "attributeGroup":
Laurent@814:             attrgroup = factory.FindSchemaElement(element["ref"], ATTRIBUTESGROUP)
Laurent@814:             for attr in attrgroup["attributes"]:
Laurent@814:                 if attrnames.get(attr["name"], False):
Laurent@814:                     raise ValueError("\"%s\" attribute has been defined two times!" % attr["name"])
Laurent@814:                 else:
Laurent@814:                     attrnames[attr["name"]] = True
Laurent@814:                     attrs.append(attr)
Laurent@814:         elif element["type"] == "anyAttribute":
Laurent@814:             raise ValueError("\"anyAttribute\" element isn't supported yet!")
Laurent@814:     return attrs
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceRestriction(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     restriction = {"type": "restriction", "base": attributes.get("base", None), "facets": [], "doc": annotations}
Laurent@814:     if len(children) > 0 and children[0]["type"] == SIMPLETYPE:
Laurent@814:         if restriction["base"] is None:
Laurent@814:             restriction["base"] = children.pop(0)
Laurent@814:         else:
Laurent@814:             raise ValueError("Only one base type can be defined for restriction!")
Laurent@814:     if restriction["base"] is None:
Laurent@814:         raise ValueError("No base type has been defined for restriction!")
Laurent@814:     
Laurent@814:     while len(children) > 0 and children[0]["type"] in ALL_FACETS:
Laurent@814:         restriction["facets"].append(children.pop(0))
Laurent@814:     restriction["attributes"] = ExtractAttributes(factory, children, restriction["base"])
Laurent@814:     return restriction
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceExtension(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     if not attributes.has_key("base"):
Laurent@814:         raise ValueError("No base type has been defined for extension!")
Laurent@814:     extension = {"type": "extension", "attributes": [], "elements": [], "base": attributes["base"], "doc": annotations}
Laurent@814:     if len(children) > 0:
Laurent@814:         if children[0]["type"] in ["group", "all", CHOICE, "sequence"]:
Laurent@814:             group = children.pop(0)
Laurent@814:             if group["type"] in ["all", "sequence"]:
Laurent@814:                 extension["elements"] = group["elements"]
Laurent@814:                 extension["order"] = group["order"]
Laurent@814:             elif group["type"] == CHOICE:
Laurent@814:                 content = group.copy()
Laurent@814:                 content["name"] = "content"
Laurent@814:                 extension["elements"].append(content)
Laurent@814:             elif group["type"] == "group":
Laurent@814:                 elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP)
Laurent@814:                 if elmtgroup.has_key("elements"):
Laurent@814:                     extension["elements"] = elmtgroup["elements"]
Laurent@814:                     extension["order"] = elmtgroup["order"]
Laurent@814:                 else:
Laurent@814:                     content = elmtgroup.copy()
Laurent@814:                     content["name"] = "content"
Laurent@814:                     extension["elements"].append(content)
Laurent@814:         extension["attributes"] = ExtractAttributes(factory, children)
Laurent@814:     return extension
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceSimpleContent(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     simpleContent = children[0].copy()
Laurent@814:     
Laurent@814:     basetypeinfos = factory.FindSchemaElement(simpleContent["base"])
Laurent@814:     if basetypeinfos["type"] == SIMPLETYPE:
Laurent@814:         contenttypeinfos = simpleContent.copy()
Laurent@814:         simpleContent.pop("base")
Laurent@814:     elif basetypeinfos["type"] == COMPLEXTYPE and \
Laurent@814:          len(basetypeinfos["elements"]) == 1 and \
Laurent@814:          basetypeinfos["elements"][0]["name"] == "content" and \
Laurent@814:          basetypeinfos["elements"][0].has_key("elmt_type") and \
Laurent@814:          basetypeinfos["elements"][0]["elmt_type"]["type"] == SIMPLETYPE:
Laurent@814:         contenttypeinfos = simpleContent.copy()
Laurent@814:         contenttypeinfos["base"] = basetypeinfos["elements"][0]["elmt_type"]
Laurent@814:     else:
Laurent@814:         raise ValueError("No compatible base type defined for simpleContent!")
Laurent@814:     contenttypeinfos = CreateSimpleType(factory, attributes, contenttypeinfos)
Laurent@814:     
Laurent@814:     simpleContent["elements"] = [{"name": "content", "type": ELEMENT,
Laurent@814:                                   "elmt_type": contenttypeinfos, "doc": annotations,
Laurent@814:                                   "minOccurs": 1, "maxOccurs": 1}]
Laurent@814:     simpleContent["type"] = "simpleContent"
Laurent@814:     return simpleContent
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceComplexContent(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     complexContent = children[0].copy()
Laurent@814:     complexContent["type"] = "complexContent"
Laurent@814:     return complexContent
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceComplexType(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     if len(children) > 0:
Laurent@814:         if children[0]["type"] in ["simpleContent", "complexContent"]:
Laurent@814:             complexType = children[0].copy()
Laurent@814:             complexType.update(attributes)
Laurent@814:             complexType["type"] = COMPLEXTYPE
Laurent@814:             return complexType
Laurent@814:         elif children[0]["type"] in ["group", "all", CHOICE, "sequence"]:
Laurent@814:             complexType = {"type": COMPLEXTYPE, "elements": [], "order": True, "doc": annotations}
Laurent@814:             complexType.update(attributes)
Laurent@814:             group = children.pop(0)
Laurent@814:             if group["type"] in ["all", "sequence"]:
Laurent@814:                 choice_number = 0
Laurent@814:                 for element in group["elements"]:
Laurent@814:                     if element["type"] == CHOICE:
Laurent@814:                         choice_number += 1
Laurent@814:                 if (group["minOccurs"] == 0 or group["maxOccurs"] != 1) and len(group["elements"]) > 1 or choice_number > 1:
Laurent@814:                     content = {"type": CHOICE, "name": "content", "choices": [group], "minOccurs": 1, "maxOccurs": 1}
Laurent@814:                     complexType["elements"].append(content)
Laurent@814:                 else:
Laurent@814:                     if len(group["elements"]) == 1:
Laurent@814:                         if group["minOccurs"] == 0:
Laurent@814:                             group["elements"][0]["minOccurs"] = group["minOccurs"]
Laurent@814:                         if group["maxOccurs"] != 1:
Laurent@814:                             group["elements"][0]["maxOccurs"] = group["maxOccurs"]
Laurent@814:                     for element in group["elements"]:
Laurent@814:                         if element["type"] == CHOICE:
Laurent@814:                             element["name"] = "content"
Laurent@814:                     complexType["elements"] = group["elements"]
Laurent@814:                     complexType["order"] = group["order"]
Laurent@814:             elif group["type"] == CHOICE:
Laurent@814:                 content = group.copy()
Laurent@814:                 content["name"] = "content"
Laurent@814:                 complexType["elements"].append(content)
Laurent@814:             elif group["type"] == "group":
Laurent@814:                 elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP)
Laurent@814:                 if elmtgroup.has_key("elements"):
Laurent@814:                     complexType["elements"] = elmtgroup["elements"]
Laurent@814:                     complexType["order"] = elmtgroup["order"]
Laurent@814:                 else:
Laurent@814:                     content = elmtgroup.copy()
Laurent@814:                     content["name"] = "content"
Laurent@814:                     complexType["elements"].append(content)
Laurent@814:         else:
Laurent@814:             complexType = {"elements": [], "order": True, "doc": annotations}
Laurent@814:             complexType.update(attributes)
Laurent@814:             complexType["type"] = COMPLEXTYPE
Laurent@814:         complexType["attributes"] = ExtractAttributes(factory, children)
Laurent@814:         return complexType
Laurent@814:     else:
Laurent@814:         raise ValueError("\"ComplexType\" can't be empty!")
Laurent@814: 
Laurent@814: 
Laurent@814: # Attribute elements
Laurent@814: 
Laurent@814: def ReduceAnyAttribute(factory, attributes, elements):
Laurent@814:     return {"type" : "anyAttribute"}
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceAttribute(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     if attributes.has_key("default"):
Laurent@814:         if attributes.has_key("fixed"):
Laurent@814:             raise ValueError("\"default\" and \"fixed\" can't be defined at the same time!")
Laurent@814:         elif attributes.get("use", "optional") != "optional":
Laurent@814:             raise ValueError("if \"default\" present, \"use\" can only have the value \"optional\"!")
Laurent@814:     
Laurent@814:     attribute = {"type": ATTRIBUTE, "attr_type": attributes.get("type", None), "doc": annotations}
Laurent@814:     if len(children) > 0:
Laurent@814:         if attribute["attr_type"] is None:
Laurent@814:             attribute["attr_type"] = children[0]
Laurent@814:         else:
Laurent@814:             raise ValueError("Only one type can be defined for attribute!")
Laurent@814:     
Laurent@814:     if attributes.has_key("ref"):
Laurent@814:         if attributes.has_key("name"):
Laurent@814:             raise ValueError("\"ref\" and \"name\" can't be defined at the same time!")
Laurent@814:         elif attributes.has_key("form"):
Laurent@814:             raise ValueError("\"ref\" and \"form\" can't be defined at the same time!")
Laurent@814:         elif attribute["attr_type"] is not None:
Laurent@814:             raise ValueError("if \"ref\" is present, no type can be defined!")
Laurent@814:     elif attribute["attr_type"] is None:
Laurent@814:         raise ValueError("No type has been defined for attribute \"%s\"!" % attributes["name"])
Laurent@814:     
Laurent@814:     if attributes.has_key("type"):
Laurent@814:         tmp_attrs = attributes.copy()
Laurent@814:         tmp_attrs.pop("type")
Laurent@814:         attribute.update(tmp_attrs)
Laurent@814:     else:
Laurent@814:         attribute.update(attributes)
Laurent@814:     return attribute
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceAttributeGroup(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     if attributes.has_key("ref"):
Laurent@814:         return {"type": "attributeGroup", "ref": attributes["ref"], "doc": annotations}
Laurent@814:     else:
Laurent@814:         return {"type": ATTRIBUTESGROUP, "attributes": ExtractAttributes(factory, children), "doc": annotations}
Laurent@814: 
Laurent@814: 
Laurent@814: # Elements groups
Laurent@814: 
Laurent@814: def ReduceAny(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     any = {"type": ANY, "doc": annotations}
Laurent@814:     any.update(attributes)
Laurent@814:     return any
Laurent@814: 
Laurent@814: def ReduceElement(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     types = []
Laurent@814:     constraints = []
Laurent@814:     for child in children:
Laurent@814:         if child["type"] == CONSTRAINT:
Laurent@814:             constraints.append(child)
Laurent@814:         else:
Laurent@814:             types.append(child)
Laurent@814:     
Laurent@814:     if attributes.has_key("default") and attributes.has_key("fixed"):
Laurent@814:         raise ValueError("\"default\" and \"fixed\" can't be defined at the same time!")
Laurent@814:     
Laurent@814:     if attributes.has_key("ref"):
Laurent@814:         for attr in ["name", "default", "fixed", "form", "block", "type"]:
Laurent@814:             if attributes.has_key(attr):
Laurent@814:                 raise ValueError("\"ref\" and \"%s\" can't be defined at the same time!" % attr)
Laurent@814:         if attributes.has_key("nillable"):
Laurent@814:             raise ValueError("\"ref\" and \"nillable\" can't be defined at the same time!")
Laurent@814:         if len(types) > 0:
Laurent@814:             raise ValueError("No type and no constraints can be defined where \"ref\" is defined!")
Laurent@814:     
Laurent@814:         infos = factory.FindSchemaElement(attributes["ref"], ELEMENT)
Laurent@814:         if infos is not None:
Laurent@814:             element = infos.copy()
Laurent@814:             element["constraints"] = constraints
Laurent@814:             element["minOccurs"] = attributes["minOccurs"]
Laurent@814:             element["maxOccurs"] = attributes["maxOccurs"]
Laurent@814:             return element
Laurent@814:         else:
Laurent@814:             raise ValueError("\"%s\" base type isn't defined or circular referenced!" % name)
Laurent@814:     
Laurent@814:     elif attributes.has_key("name"):
Laurent@814:         element = {"type": ELEMENT, "elmt_type": attributes.get("type", None), "constraints": constraints, "doc": annotations}
Laurent@814:         if len(types) > 0:
Laurent@814:             if element["elmt_type"] is None:
Laurent@814:                 element["elmt_type"] = types[0]
Laurent@814:             else:
Laurent@814:                 raise ValueError("Only one type can be defined for attribute!")
Laurent@814:         elif element["elmt_type"] is None:
Laurent@814:             element["elmt_type"] = "tag"
Laurent@814:             element["type"] = TAG
Laurent@814:         
Laurent@814:         if attributes.has_key("type"):
Laurent@814:             tmp_attrs = attributes.copy()
Laurent@814:             tmp_attrs.pop("type")
Laurent@814:             element.update(tmp_attrs)
Laurent@814:         else:
Laurent@814:             element.update(attributes)
Laurent@814:         return element
Laurent@814:     else:
Laurent@814:         raise ValueError("\"Element\" must have at least a \"ref\" or a \"name\" defined!")
Laurent@814: 
Laurent@814: def ReduceAll(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     for child in children:
Laurent@814:         if children["maxOccurs"] == "unbounded" or children["maxOccurs"] > 1:
Laurent@814:             raise ValueError("\"all\" item can't have \"maxOccurs\" attribute greater than 1!")
Laurent@814:     
Laurent@814:     return {"type": "all", "elements": children, "minOccurs": attributes["minOccurs"],
Laurent@814:             "maxOccurs": attributes["maxOccurs"], "order": False, "doc": annotations}
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceChoice(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     choices = []
Laurent@814:     for child in children:
Laurent@814:         if child["type"] in [ELEMENT, ANY, TAG]:
Laurent@814:             choices.append(child)
Laurent@814:         elif child["type"] == "sequence":
Laurent@814:             child["minOccurs"] = child["maxOccurs"] = 1
Laurent@814:             choices.append(child)
Laurent@814:             #raise ValueError("\"sequence\" in \"choice\" is not supported. Create instead a new complex type!")
Laurent@814:         elif child["type"] == CHOICE:
Laurent@814:             choices.extend(child["choices"])
Laurent@814:         elif child["type"] == "group":
Laurent@814:             elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP) 
Laurent@814:             if not elmtgroup.has_key("choices"):
Laurent@814:                 raise ValueError("Only group composed of \"choice\" can be referenced in \"choice\" element!")
Laurent@814:             choices_tmp = []
Laurent@814:             for choice in elmtgroup["choices"]:
Laurent@814:                 if not isinstance(choice["elmt_type"], (UnicodeType, StringType)) and choice["elmt_type"]["type"] == COMPLEXTYPE:
Laurent@814:                     elmt_type = "%s_%s" % (elmtgroup["name"], choice["name"])
Laurent@814:                     if factory.TargetNamespace is not None:
Laurent@814:                         elmt_type = "%s:%s" % (factory.TargetNamespace, elmt_type)
Laurent@814:                     new_choice = choice.copy()
Laurent@814:                     new_choice["elmt_type"] = elmt_type
Laurent@814:                     choices_tmp.append(new_choice)
Laurent@814:                 else:
Laurent@814:                     choices_tmp.append(choice)
Laurent@814:             choices.extend(choices_tmp)
Laurent@814:     
Laurent@814:     for choice in choices:
Laurent@814:         attributes["minOccurs"] = min(attributes["minOccurs"], choice["minOccurs"])
Laurent@814:         choice["minOccurs"] = 1
Laurent@814:     
Laurent@814:     return {"type": CHOICE, "choices": choices, "minOccurs": attributes["minOccurs"],
Laurent@814:             "maxOccurs": attributes["maxOccurs"], "doc": annotations}
Laurent@814: 
Laurent@814: 
Laurent@814: def ReduceSequence(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     sequence = []
Laurent@814:     for child in children:
Laurent@814:         if child["type"] in [ELEMENT, ANY, TAG, CHOICE]:
Laurent@814:             sequence.append(child)
Laurent@814:         elif child["type"] == "sequence":
Laurent@814:             sequence.extend(child["elements"])
Laurent@814:         elif child["type"] == "group":
Laurent@814:             elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP)
Laurent@814:             if not elmtgroup.has_key("elements") or not elmtgroup["order"]:
Laurent@814:                 raise ValueError("Only group composed of \"sequence\" can be referenced in \"sequence\" element!")
Laurent@814:             elements_tmp = []
Laurent@814:             for element in elmtgroup["elements"]:
Laurent@814:                 if not isinstance(element["elmt_type"], (UnicodeType, StringType)) and element["elmt_type"]["type"] == COMPLEXTYPE:
Laurent@814:                     elmt_type = "%s_%s"%(elmtgroup["name"], element["name"])
Laurent@814:                     if factory.TargetNamespace is not None:
Laurent@814:                         elmt_type = "%s:%s" % (factory.TargetNamespace, elmt_type)
Laurent@814:                     new_element = element.copy()
Laurent@814:                     new_element["elmt_type"] = elmt_type
Laurent@814:                     elements_tmp.append(new_element)
Laurent@814:                 else:
Laurent@814:                     elements_tmp.append(element)
Laurent@814:             sequence.extend(elements_tmp)
Laurent@814:             
Laurent@814:     return {"type": "sequence", "elements": sequence, "minOccurs": attributes["minOccurs"],
Laurent@814:             "maxOccurs": attributes["maxOccurs"], "order": True, "doc": annotations}
Laurent@814:     
Laurent@814:     
Laurent@814: def ReduceGroup(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     if attributes.has_key("ref"):
Laurent@814:         return {"type": "group", "ref": attributes["ref"], "doc": annotations}
Laurent@814:     else:
Laurent@814:         element = children[0]
Laurent@814:         group = {"type": ELEMENTSGROUP, "doc": annotations}
Laurent@814:         if element["type"] == CHOICE:
Laurent@814:             group["choices"] = element["choices"]
Laurent@814:         else:
Laurent@814:             group.update({"elements": element["elements"], "order": group["order"]})
Laurent@814:         group.update(attributes)
Laurent@814:         return group
Laurent@814: 
Laurent@814: # Constraint elements
Laurent@814: 
Laurent@814: def ReduceUnique(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     unique = {"type": CONSTRAINT, "const_type": "unique", "selector": children[0], "fields": children[1:]}
Laurent@814:     unique.update(attributes)
Laurent@814:     return unique
Laurent@814:     
Laurent@814: def ReduceKey(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     key = {"type": CONSTRAINT, "const_type": "key", "selector": children[0], "fields": children[1:]}
Laurent@814:     key.update(attributes)
Laurent@814:     return key
Laurent@814: 
Laurent@814: def ReduceKeyRef(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     keyref = {"type": CONSTRAINT, "const_type": "keyref", "selector": children[0], "fields": children[1:]}
Laurent@814:     keyref.update(attributes)
Laurent@814:     return keyref
Laurent@814:     
Laurent@814: def ReduceSelector(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     selector = {"type": CONSTRAINT, "const_type": "selector"}
Laurent@814:     selector.update(attributes)
Laurent@814:     return selector
Laurent@814: 
Laurent@814: def ReduceField(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     field = {"type": CONSTRAINT, "const_type": "field"}
Laurent@814:     field.update(attributes)
Laurent@814:     return field
Laurent@814:     
Laurent@814: 
Laurent@814: # Inclusion elements
Laurent@814: 
Laurent@814: def ReduceImport(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     raise ValueError("\"import\" element isn't supported yet!")
Laurent@814: 
Laurent@814: def ReduceInclude(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     
Laurent@814:     if factory.FileName is None:
Laurent@814:         raise ValueError("Include in XSD string not yet supported")
Laurent@814:     filepath = attributes["schemaLocation"]
Laurent@814:     if filepath is not None and not os.path.exists(filepath):
Laurent@814:         filepath = os.path.join(factory.BaseFolder, filepath)
Laurent@814:         if not os.path.exists(filepath):
Laurent@814:             raise ValueError("No file '%s' found for include" % attributes["schemaLocation"])
Laurent@814:     xsdfile = open(filepath, 'r')
Laurent@814:     include_factory = XSDClassFactory(minidom.parse(xsdfile), filepath)
Laurent@814:     xsdfile.close()
Laurent@814:     include_factory.CreateClasses()
Laurent@814:     
Laurent@814:     if factory.TargetNamespace == include_factory.TargetNamespace:
Laurent@814:         factory.Namespaces[factory.TargetNamespace].update(include_factory.Namespaces[include_factory.TargetNamespace])
Laurent@814:     else:
Laurent@814:         factory.Namespaces[include_factory.TargetNamespace] = include_factory.Namespaces[include_factory.TargetNamespace]
Laurent@814:     factory.ComputedClasses.update(include_factory.ComputedClasses)
Laurent@1322:     factory.ComputedClassesLookUp.update(include_factory.ComputedClassesLookUp)
Laurent@1322:     factory.EquivalentClassesParent.update(include_factory.EquivalentClassesParent)
Laurent@814:     return None
Laurent@814:     
Laurent@814: def ReduceRedefine(factory, attributes, elements):
Laurent@814:     annotations, children = factory.ReduceElements(elements)
Laurent@814:     raise ValueError("\"redefine\" element isn't supported yet!")
Laurent@814: 
Laurent@814: 
Laurent@814: # Schema element
Laurent@814: 
Laurent@814: def ReduceSchema(factory, attributes, elements):
Laurent@814:     factory.AttributeFormDefault = attributes["attributeFormDefault"]
Laurent@814:     factory.ElementFormDefault = attributes["elementFormDefault"]
Laurent@814:     factory.BlockDefault = attributes["blockDefault"]
Laurent@814:     factory.FinalDefault = attributes["finalDefault"]
Laurent@814:     
Laurent@1315:     targetNamespace = attributes.get("targetNamespace", None)
Laurent@1315:     factory.TargetNamespace = factory.DefinedNamespaces.get(targetNamespace, None)
Laurent@1290:     if factory.TargetNamespace is not None:
Laurent@1315:         factory.etreeNamespaceFormat = "{%s}%%s" % targetNamespace
Laurent@814:     factory.Namespaces[factory.TargetNamespace] = {}
Laurent@814:     
Laurent@814:     annotations, children = factory.ReduceElements(elements, True)
Laurent@814:     
Laurent@814:     for child in children:
Laurent@814:         if child.has_key("name"):
Laurent@814:             infos = factory.GetQualifiedNameInfos(child["name"], factory.TargetNamespace, True)
Laurent@814:             if infos is None:
Laurent@814:                 factory.Namespaces[factory.TargetNamespace][child["name"]] = child
Laurent@814:             elif not CompareSchema(infos, child):
Laurent@814:                 raise ValueError("\"%s\" is defined twice in targetNamespace!" % child["name"])
Laurent@814: 
Laurent@814: def CompareSchema(schema, reference):
Laurent@814:     if isinstance(schema, ListType):
Laurent@814:         if not isinstance(reference, ListType) or len(schema) != len(reference):
Laurent@814:             return False
Laurent@814:         for i, value in enumerate(schema):
Laurent@814:             result = CompareSchema(value, reference[i])
Laurent@814:             if not result:
Laurent@814:                 return result
Laurent@814:         return True
Laurent@814:     elif isinstance(schema, DictType):
Laurent@814:         if not isinstance(reference, DictType) or len(schema) != len(reference):
Laurent@814:             return False
Laurent@814:         for name, value in schema.items():
Laurent@814:             ref_value = reference.get(name, None)
Laurent@814:             if ref_value is None and value != None:
Laurent@814:                 return False
Laurent@814:             result = CompareSchema(value, ref_value)
Laurent@814:             if not result:
Laurent@814:                 return result
Laurent@814:         return True
Laurent@814:     elif isinstance(schema, FunctionType):
Laurent@814:         if not isinstance(reference, FunctionType) or schema.__name__ != reference.__name__:
Laurent@814:             return False
Laurent@814:         else:
Laurent@814:             return True
Laurent@814:     return schema == reference
Laurent@814:     
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: #                       Base class for XSD schema extraction
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: 
Laurent@814: 
Laurent@814: class XSDClassFactory(ClassFactory):
Laurent@814: 
Laurent@814:     def __init__(self, document, filepath=None, debug=False):
Laurent@814:         ClassFactory.__init__(self, document, filepath, debug)
Laurent@814:         self.Namespaces["xml"] = {
Laurent@814:             "lang": {
Laurent@814:                 "type": SYNTAXATTRIBUTE, 
Laurent@814:                 "extract": {
Laurent@814:                     "default": GenerateModelNameExtraction("lang", LANGUAGE_model)
Laurent@814:                 }
Laurent@814:             }
Laurent@814:         }
Laurent@814:         self.Namespaces["xsi"] = {
Laurent@814:             "noNamespaceSchemaLocation": {
Laurent@814:                 "type": SYNTAXATTRIBUTE, 
Laurent@814:                 "extract": {
Laurent@814:                     "default": NotSupportedYet("noNamespaceSchemaLocation")
Laurent@814:                 }
Laurent@814:             },
Laurent@814:             "nil": {
Laurent@814:                 "type": SYNTAXATTRIBUTE, 
Laurent@814:                 "extract": {
Laurent@814:                     "default": NotSupportedYet("nil")
Laurent@814:                 }
Laurent@814:             },
Laurent@814:             "schemaLocation": {
Laurent@814:                 "type": SYNTAXATTRIBUTE, 
Laurent@814:                 "extract": {
Laurent@814:                     "default": NotSupportedYet("schemaLocation")
Laurent@814:                 }
Laurent@814:             },
Laurent@814:             "type": {
Laurent@814:                 "type": SYNTAXATTRIBUTE, 
Laurent@814:                 "extract": {
Laurent@814:                     "default": NotSupportedYet("type")
Laurent@814:                 }
Laurent@814:             }
Laurent@814:         }
Laurent@814:         
Laurent@814:     def ParseSchema(self):
Laurent@814:         for child in self.Document.childNodes:
Laurent@814:             if child.nodeType == self.Document.ELEMENT_NODE:
Laurent@814:                 schema = child
Laurent@814:                 break
Laurent@814:         for qualified_name, attr in schema._attrs.items():
Laurent@1290:             namespace, name = DecomposeQualifiedName(qualified_name)
Laurent@1290:             if namespace == "xmlns":
Laurent@1290:                 value = GetAttributeValue(attr)
Laurent@1290:                 self.DefinedNamespaces[value] = name
Laurent@1290:                 self.NSMAP[name] = value
Laurent@1290:                 if value == "http://www.w3.org/2001/XMLSchema":
Laurent@814:                     self.SchemaNamespace = name
Laurent@1290:                     self.Namespaces[self.SchemaNamespace] = XSD_NAMESPACE
Laurent@814:         self.Schema = XSD_NAMESPACE["schema"]["extract"]["default"](self, schema)
Laurent@814:         ReduceSchema(self, self.Schema[1], self.Schema[2])
Laurent@814: 
Laurent@814:     def FindSchemaElement(self, element_name, element_type=None):
Laurent@814:         namespace, name = DecomposeQualifiedName(element_name)
Laurent@814:         element = self.GetQualifiedNameInfos(name, namespace, True)
Laurent@814:         if element is None and namespace == self.TargetNamespace and name not in self.CurrentCompilations:
Laurent@814:             self.CurrentCompilations.append(name)
Laurent@814:             element = self.CreateSchemaElement(name, element_type)
Laurent@814:             self.CurrentCompilations.pop(-1)
Laurent@814:             if element is not None:
Laurent@814:                 self.Namespaces[self.TargetNamespace][name] = element
Laurent@814:         if element is None:
Laurent@814:             if name in self.CurrentCompilations:
Laurent@814:                 if self.Debug:
Laurent@814:                     print "Warning : \"%s\" is circular referenced!" % element_name
Laurent@814:             else:
Laurent@814:                 raise ValueError("\"%s\" isn't defined!" % element_name)
Laurent@814:         if element_type is not None and element["type"] != element_type:
Laurent@814:             raise ValueError("\"%s\" isn't of the expected type!" % element_name)
Laurent@814:         return element
Laurent@814:     
Laurent@814:     def CreateSchemaElement(self, element_name, element_type):
Laurent@814:         for type, attributes, elements in self.Schema[2]:
Laurent@814:             namespace, name = DecomposeQualifiedName(type)
Laurent@814:             if attributes.get("name", None) == element_name:
Laurent@814:                 element_infos = None
Laurent@814:                 if element_type in (ATTRIBUTE, None) and name == "attribute":
Laurent@814:                     element_infos = ReduceAttribute(self, attributes, elements)
Laurent@814:                 elif element_type in (ELEMENT, None) and name == "element":
Laurent@814:                     element_infos = ReduceElement(self, attributes, elements)
Laurent@814:                 elif element_type in (ATTRIBUTESGROUP, None) and name == "attributeGroup":
Laurent@814:                     element_infos = ReduceAttributeGroup(self, attributes, elements)
Laurent@814:                 elif element_type in (ELEMENTSGROUP, None) and name == "group":
Laurent@814:                     element_infos = ReduceGroup(self, attributes, elements)
Laurent@814:                 elif element_type in (SIMPLETYPE, None) and name == "simpleType":
Laurent@814:                     element_infos = ReduceSimpleType(self, attributes, elements)
Laurent@814:                 elif element_type in (COMPLEXTYPE, None) and name == "complexType":
Laurent@814:                     element_infos = ReduceComplexType(self, attributes, elements)
Laurent@814:                 if element_infos is not None:
Laurent@814:                     self.Namespaces[self.TargetNamespace][element_name] = element_infos
Laurent@814:                     return element_infos
Laurent@814:         return None
Laurent@814: 
Laurent@814: """
Laurent@1290: This function opens the xsd file and generate a xml parser with class lookup from 
Laurent@1290: the xml tree
Laurent@814: """
Laurent@1290: def GenerateParserFromXSD(filepath):
Laurent@814:     xsdfile = open(filepath, 'r')
Laurent@1290:     xsdstring = xsdfile.read()
Laurent@814:     xsdfile.close()
Laurent@1322:     cwd = os.getcwd()
Laurent@1322:     os.chdir(os.path.dirname(filepath))
Laurent@1322:     parser = GenerateParser(XSDClassFactory(minidom.parseString(xsdstring), filepath), xsdstring)
Laurent@1322:     os.chdir(cwd)
Laurent@1322:     return parser
Laurent@814: 
Laurent@814: """
Laurent@1290: This function generate a xml from the xsd given as a string
Laurent@814: """
Laurent@1290: def GenerateParserFromXSDstring(xsdstring):
Laurent@1315:     return GenerateParser(XSDClassFactory(minidom.parseString(xsdstring)), xsdstring)
Laurent@814: 
Laurent@814: 
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: #                           XSD schema syntax elements
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: 
Laurent@814: XSD_NAMESPACE = {
Laurent@814: 
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: #                           Syntax elements definition
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: 
Laurent@814:     "all": {"struct": """
Laurent@814:         <all
Laurent@814:           id = ID
Laurent@814:           maxOccurs = 1 : 1
Laurent@814:           minOccurs = (0 | 1) : 1
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, element*)
Laurent@814:         </all>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("all", ["id", "maxOccurs", "minOccurs"], 
Laurent@814:                 re.compile("((?:annotation )?(?:element )*)"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceAll
Laurent@814:     },
Laurent@814: 
Laurent@814:     "annotation": {"struct": """
Laurent@814:         <annotation
Laurent@814:           id = ID
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (appinfo | documentation)*
Laurent@814:         </annotation>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("annotation", ["id"], 
Laurent@814:                 re.compile("((?:app_info |documentation )*)"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceAnnotation
Laurent@814:     },
Laurent@814: 
Laurent@814:     "any": {"struct": """
Laurent@814:         <any
Laurent@814:           id = ID
Laurent@814:           maxOccurs = (nonNegativeInteger | unbounded)  : 1
Laurent@814:           minOccurs = nonNegativeInteger : 1
Laurent@814:           namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
Laurent@814:           processContents = (lax | skip | strict) : strict
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </any>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("any", 
Laurent@814:                 ["id", "maxOccurs", "minOccurs", "namespace", "processContents"], 
Laurent@814:                 re.compile("((?:annotation )?(?:simpleType )*)"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceAny
Laurent@814:     },
Laurent@814: 
Laurent@814:     "anyAttribute": {"struct": """
Laurent@814:         <anyAttribute
Laurent@814:           id = ID
Laurent@814:           namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
Laurent@814:           processContents = (lax | skip | strict) : strict
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </anyAttribute>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("anyAttribute",
Laurent@814:                 ["id", "namespace", "processContents"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": ReduceAnyAttribute
Laurent@814:     },
Laurent@814: 
Laurent@814:     "appinfo": {"struct": """
Laurent@814:         <appinfo
Laurent@814:           source = anyURI
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: ({any})*
Laurent@814:         </appinfo>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("appinfo", ["source"], re.compile("(.*)"), True)
Laurent@814:         },
Laurent@814:         "reduce": ReduceAppInfo
Laurent@814:     },
Laurent@814: 
Laurent@814:     "attribute": {"struct": """
Laurent@814:         <attribute
Laurent@814:           default = string
Laurent@814:           fixed = string
Laurent@814:           form = (qualified | unqualified)
Laurent@814:           id = ID
Laurent@814:           name = NCName
Laurent@814:           ref = QName
Laurent@814:           type = QName
Laurent@814:           use = (optional | prohibited | required) : optional
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, simpleType?)
Laurent@814:         </attribute>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("attribute", 
Laurent@814:                 ["default", "fixed", "form", "id", "name", "ref", "type", "use"], 
Laurent@814:                 re.compile("((?:annotation )?(?:simpleType )?)")),
Laurent@814:             "schema": GenerateElement("attribute", 
Laurent@814:                 ["default", "fixed", "form", "id", "name", "type"], 
Laurent@814:                 re.compile("((?:annotation )?(?:simpleType )?)"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceAttribute
Laurent@814:     },
Laurent@814: 
Laurent@814:     "attributeGroup": {"struct": """
Laurent@814:         <attributeGroup
Laurent@814:           id = ID
Laurent@814:           name = NCName
Laurent@814:           ref = QName
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?))
Laurent@814:         </attributeGroup>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("attributeGroup", 
Laurent@814:                 ["id", "ref"], ONLY_ANNOTATION),
Laurent@814:             "schema": GenerateElement("attributeGroup",
Laurent@814:                 ["id", "name"], 
Laurent@814:                 re.compile("((?:annotation )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceAttributeGroup
Laurent@814:     },
Laurent@814: 
Laurent@814:     "choice": {"struct": """
Laurent@814:         <choice
Laurent@814:           id = ID
Laurent@814:           maxOccurs = (nonNegativeInteger | unbounded)  : 1
Laurent@814:           minOccurs = nonNegativeInteger : 1
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (element | group | choice | sequence | any)*)
Laurent@814:         </choice>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("choice", ["id", "maxOccurs", "minOccurs"], 
Laurent@814:                 re.compile("((?:annotation )?(?:element |group |choice |sequence |any )*)"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceChoice
Laurent@814:     },
Laurent@814: 
Laurent@814:     "complexContent": {"struct": """
Laurent@814:         <complexContent
Laurent@814:           id = ID
Laurent@814:           mixed = boolean
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (restriction | extension))
Laurent@814:         </complexContent>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("complexContent", ["id", "mixed"], 
Laurent@814:                 re.compile("((?:annotation )?(?:restriction |extension ))"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceComplexContent
Laurent@814:     },
Laurent@814: 
Laurent@814:     "complexType": {"struct": """
Laurent@814:         <complexType
Laurent@814:           abstract = boolean : false
Laurent@814:           block = (#all | List of (extension | restriction))
Laurent@814:           final = (#all | List of (extension | restriction))
Laurent@814:           id = ID
Laurent@814:           mixed = boolean : false
Laurent@814:           name = NCName
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
Laurent@814:         </complexType>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("complexType", 
Laurent@814:                 ["abstract", "block", "final", "id", "mixed", "name"], 
Laurent@814:                 re.compile("((?:annotation )?(?:simpleContent |complexContent |(?:(?:group |all |choice |sequence )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))))"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceComplexType
Laurent@814:     },
Laurent@814: 
Laurent@814:     "documentation": {"struct" : """
Laurent@814:         <documentation
Laurent@814:           source = anyURI
Laurent@814:           xml:lang = language
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: ({any})*
Laurent@814:         </documentation>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("documentation", 
Laurent@814:                 ["source", "lang"], re.compile("(.*)"), True)
Laurent@814:         },
Laurent@814:         "reduce": ReduceDocumentation
Laurent@814:     },
Laurent@814: 
Laurent@814:     "element": {"struct": """
Laurent@814:         <element
Laurent@814:           abstract = boolean : false
Laurent@814:           block = (#all | List of (extension | restriction | substitution))
Laurent@814:           default = string
Laurent@814:           final = (#all | List of (extension | restriction))
Laurent@814:           fixed = string
Laurent@814:           form = (qualified | unqualified)
Laurent@814:           id = ID
Laurent@814:           maxOccurs = (nonNegativeInteger | unbounded)  : 1
Laurent@814:           minOccurs = nonNegativeInteger : 1
Laurent@814:           name = NCName
Laurent@814:           nillable = boolean : false
Laurent@814:           ref = QName
Laurent@814:           substitutionGroup = QName
Laurent@814:           type = QName
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
Laurent@814:         </element>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("element", 
Laurent@814:                 ["abstract", "block", "default", "final", "fixed", "form", "id", "maxOccurs", "minOccurs", "name", "nillable", "ref", "substitutionGroup", "type"], 
Laurent@814:                 re.compile("((?:annotation )?(?:simpleType |complexType )?(?:unique |key |keyref )*)")),
Laurent@814:             "schema": GenerateElement("element", 
Laurent@814:                 ["abstract", "block", "default", "final", "fixed", "form", "id", "name", "nillable", "substitutionGroup", "type"], 
Laurent@814:                 re.compile("((?:annotation )?(?:simpleType |complexType )?(?:unique |key |keyref )*)"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceElement
Laurent@814:     },
Laurent@814: 
Laurent@814:     "enumeration": {"struct": """
Laurent@814:         <enumeration
Laurent@814:           id = ID
Laurent@814:           value = anySimpleType
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </enumeration>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("enumeration", ["id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("enumeration", False)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "extension": {"struct": """
Laurent@814:         <extension
Laurent@814:           base = QName
Laurent@814:           id = ID
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))
Laurent@814:         </extension>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("extension", ["base", "id"], 
Laurent@814:                 re.compile("((?:annotation )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))")),
Laurent@814:             "complexContent": GenerateElement("extension", ["base", "id"], 
Laurent@814:                 re.compile("((?:annotation )?(?:group |all |choice |sequence )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceExtension
Laurent@814:     },
Laurent@814: 
Laurent@814:     "field": {"struct": """
Laurent@814:         <field
Laurent@814:           id = ID
Laurent@814:           xpath = a subset of XPath expression, see below
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </field>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("field", ["id", "xpath"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": ReduceField
Laurent@814:     },
Laurent@814: 
Laurent@814:     "fractionDigits": {"struct": """
Laurent@814:         <fractionDigits
Laurent@814:           fixed = boolean : false
Laurent@814:           id = ID
Laurent@814:           value = nonNegativeInteger
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </fractionDigits>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("fractionDigits", 
Laurent@814:                 ["fixed", "id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("fractionDigits", True)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "group": {"struct": """
Laurent@814:         <group
Laurent@814:           id = ID
Laurent@814:           maxOccurs = (nonNegativeInteger | unbounded)  : 1
Laurent@814:           minOccurs = nonNegativeInteger : 1
Laurent@814:           name = NCName
Laurent@814:           ref = QName
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (all | choice | sequence)?)
Laurent@814:         </group>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("group",
Laurent@814:                 ["id", "maxOccurs", "minOccurs", "ref"], 
Laurent@814:                 re.compile("((?:annotation )?(?:all |choice |sequence )?)")),
Laurent@814:             "schema": GenerateElement("group",
Laurent@814:                 ["id", "name"], 
Laurent@814:                 re.compile("((?:annotation )?(?:all |choice |sequence )?)"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceGroup
Laurent@814:     },
Laurent@814: 
Laurent@814:     "import": {"struct": """
Laurent@814:         <import
Laurent@814:           id = ID
Laurent@814:           namespace = anyURI
Laurent@814:           schemaLocation = anyURI
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </import>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("import",
Laurent@814:                 ["id", "namespace", "schemaLocation"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": ReduceImport
Laurent@814:     },
Laurent@814: 
Laurent@814:     "include": {"struct": """
Laurent@814:         <include
Laurent@814:           id = ID
Laurent@814:           schemaLocation = anyURI
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </include>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("include",
Laurent@814:                 ["id", "schemaLocation"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": ReduceInclude
Laurent@814:     },
Laurent@814: 
Laurent@814:     "key": {"struct": """
Laurent@814:         <key
Laurent@814:           id = ID
Laurent@814:           name = NCName
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (selector, field+))
Laurent@814:         </key>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("key", ["id", "name"], 
Laurent@814:                 re.compile("((?:annotation )?(?:selector (?:field )+))"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceKey
Laurent@814:     },
Laurent@814: 
Laurent@814:     "keyref": {"struct": """
Laurent@814:         <keyref
Laurent@814:           id = ID
Laurent@814:           name = NCName
Laurent@814:           refer = QName
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (selector, field+))
Laurent@814:         </keyref>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("keyref", ["id", "name", "refer"], 
Laurent@814:                 re.compile("((?:annotation )?(?:selector (?:field )+))"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceKeyRef
Laurent@814:     },
Laurent@814: 
Laurent@814:     "length": {"struct" : """
Laurent@814:         <length
Laurent@814:           fixed = boolean : false
Laurent@814:           id = ID
Laurent@814:           value = nonNegativeInteger
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </length>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("length", 
Laurent@814:                 ["fixed", "id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("length", True)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "list": {"struct": """
Laurent@814:         <list
Laurent@814:           id = ID
Laurent@814:           itemType = QName
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, simpleType?)
Laurent@814:         </list>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("list", ["id", "itemType"], 
Laurent@814:                 re.compile("((?:annotation )?(?:simpleType )?)$"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceList
Laurent@814:     },
Laurent@814: 
Laurent@814:     "maxExclusive": {"struct": """
Laurent@814:         <maxInclusive
Laurent@814:           fixed = boolean : false
Laurent@814:           id = ID
Laurent@814:           value = anySimpleType
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </maxInclusive>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("maxExclusive",
Laurent@814:                 ["fixed", "id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("maxExclusive", True)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "maxInclusive": {"struct": """
Laurent@814:         <maxExclusive
Laurent@814:           fixed = boolean : false
Laurent@814:           id = ID
Laurent@814:           value = anySimpleType
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </maxExclusive>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("maxInclusive", 
Laurent@814:                 ["fixed", "id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("maxInclusive", True)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "maxLength": {"struct": """
Laurent@814:         <maxLength
Laurent@814:           fixed = boolean : false
Laurent@814:           id = ID
Laurent@814:           value = nonNegativeInteger
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </maxLength>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("maxLength", 
Laurent@814:                 ["fixed", "id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("maxLength", True)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "minExclusive": {"struct": """
Laurent@814:         <minExclusive
Laurent@814:           fixed = boolean : false
Laurent@814:           id = ID
Laurent@814:           value = anySimpleType
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </minExclusive>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("minExclusive", 
Laurent@814:                 ["fixed", "id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("minExclusive", True)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "minInclusive": {"struct": """
Laurent@814:         <minInclusive
Laurent@814:           fixed = boolean : false
Laurent@814:           id = ID
Laurent@814:           value = anySimpleType
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </minInclusive>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("minInclusive", 
Laurent@814:                 ["fixed", "id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("minInclusive", True)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "minLength": {"struct": """
Laurent@814:         <minLength
Laurent@814:           fixed = boolean : false
Laurent@814:           id = ID
Laurent@814:           value = nonNegativeInteger
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </minLength>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("minLength",
Laurent@814:                 ["fixed", "id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("minLength", True)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "pattern": {"struct": """
Laurent@814:         <pattern
Laurent@814:           id = ID
Laurent@814:           value = string
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </pattern>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("pattern", ["id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("pattern", False)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "redefine": {"struct": """
Laurent@814:         <redefine
Laurent@814:           id = ID
Laurent@814:           schemaLocation = anyURI
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation | (simpleType | complexType | group | attributeGroup))*
Laurent@814:         </redefine>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("refine", ["id", "schemaLocation"], 
Laurent@814:                 re.compile("((?:annotation |(?:simpleType |complexType |group |attributeGroup ))*)"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceRedefine
Laurent@814:     },
Laurent@814: 
Laurent@814:     "restriction": {"struct": """
Laurent@814:         <restriction
Laurent@814:           base = QName
Laurent@814:           id = ID
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))
Laurent@814:         </restriction>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("restriction", ["base", "id"], 
Laurent@814:                 re.compile("((?:annotation )?(?:(?:simpleType )?(?:(?:minExclusive |minInclusive |maxExclusive |maxInclusive |totalDigits |fractionDigits |length |minLength |maxLength |enumeration |whiteSpace |pattern )*)))")),
Laurent@814:             "simpleContent": GenerateElement("restriction", ["base", "id"], 
Laurent@814:                 re.compile("((?:annotation )?(?:(?:simpleType )?(?:(?:minExclusive |minInclusive |maxExclusive |maxInclusive |totalDigits |fractionDigits |length |minLength |maxLength |enumeration |whiteSpace |pattern )*)?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?)))")),
Laurent@814:             "complexContent": GenerateElement("restriction", ["base", "id"], 
Laurent@814:                 re.compile("((?:annotation )?(?:(?:simpleType )?(?:group |all |choice |sequence )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?)))")),
Laurent@814:         },
Laurent@814:         "reduce": ReduceRestriction
Laurent@814:     },
Laurent@814: 
Laurent@814:     "schema": {"struct": """
Laurent@814:         <schema
Laurent@814:           attributeFormDefault = (qualified | unqualified) : unqualified
Laurent@814:           blockDefault = (#all | List of (extension | restriction | substitution))  : ''
Laurent@814:           elementFormDefault = (qualified | unqualified) : unqualified
Laurent@814:           finalDefault = (#all | List of (extension | restriction | list | union))  : ''
Laurent@814:           id = ID
Laurent@814:           targetNamespace = anyURI
Laurent@814:           version = token
Laurent@814:           xml:lang = language
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: ((include | import | redefine | annotation)*, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*)
Laurent@814:         </schema>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("schema",
Laurent@814:                 ["attributeFormDefault", "blockDefault", "elementFormDefault", "finalDefault", "id", "targetNamespace", "version", "lang"], 
Laurent@814:                 re.compile("((?:include |import |redefine |annotation )*(?:(?:(?:simpleType |complexType |group |attributeGroup )|element |attribute |annotation )(?:annotation )*)*)"))
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "selector": {"struct": """
Laurent@814:         <selector
Laurent@814:           id = ID
Laurent@814:           xpath = a subset of XPath expression, see below
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </selector>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("selector", ["id", "xpath"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": ReduceSelector
Laurent@814:     },
Laurent@814: 
Laurent@814:     "sequence": {"struct": """
Laurent@814:         <sequence
Laurent@814:           id = ID
Laurent@814:           maxOccurs = (nonNegativeInteger | unbounded)  : 1
Laurent@814:           minOccurs = nonNegativeInteger : 1
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (element | group | choice | sequence | any)*)
Laurent@814:         </sequence>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("sequence", ["id", "maxOccurs", "minOccurs"], 
Laurent@814:                 re.compile("((?:annotation )?(?:element |group |choice |sequence |any )*)"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceSequence
Laurent@814:     },
Laurent@814: 
Laurent@814:     "simpleContent": {"struct" : """
Laurent@814:         <simpleContent
Laurent@814:           id = ID
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (restriction | extension))
Laurent@814:         </simpleContent>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("simpleContent", ["id"], 
Laurent@814:                 re.compile("((?:annotation )?(?:restriction |extension ))"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceSimpleContent
Laurent@814:     },
Laurent@814: 
Laurent@814:     "simpleType": {"struct" : """
Laurent@814:         <simpleType
Laurent@814:           final = (#all | List of (list | union | restriction))
Laurent@814:           id = ID
Laurent@814:           name = NCName
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (restriction | list | union))
Laurent@814:         </simpleType>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("simpleType", ["final", "id", "name"], 
Laurent@814:                 re.compile("((?:annotation )?(?:restriction |list |union ))"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceSimpleType
Laurent@814:     },
Laurent@814: 
Laurent@814:     "totalDigits": {"struct" : """
Laurent@814:         <totalDigits
Laurent@814:           fixed = boolean : false
Laurent@814:           id = ID
Laurent@814:           value = positiveInteger
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </totalDigits>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("totalDigits", 
Laurent@814:                 ["fixed", "id", "value"], ONLY_ANNOTATION),
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("totalDigits", True)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "union": {"struct": """
Laurent@814:         <union
Laurent@814:           id = ID
Laurent@814:           memberTypes = List of QName
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, simpleType*)
Laurent@814:         </union>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("union", ["id", "memberTypes"], 
Laurent@814:                 re.compile("((?:annotation )?(?:simpleType )*)"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceUnion
Laurent@814:     },
Laurent@814: 
Laurent@814:     "unique": {"struct": """
Laurent@814:         <unique
Laurent@814:           id = ID
Laurent@814:           name = NCName
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?, (selector, field+))
Laurent@814:         </unique>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("unique", ["id", "name"], 
Laurent@814:                 re.compile("((?:annotation )?(?:selector |(?:field )+))"))
Laurent@814:         },
Laurent@814:         "reduce": ReduceUnique
Laurent@814:     },
Laurent@814:     
Laurent@814:     "whiteSpace": {"struct" : """
Laurent@814:         <whiteSpace
Laurent@814:           fixed = boolean : false
Laurent@814:           id = ID
Laurent@814:           value = (collapse | preserve | replace)
Laurent@814:           {any attributes with non-schema namespace . . .}>
Laurent@814:           Content: (annotation?)
Laurent@814:         </whiteSpace>""",
Laurent@814:         "type": SYNTAXELEMENT, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateElement("whiteSpace", 
Laurent@814:                 ["fixed", "id", "value"], ONLY_ANNOTATION)
Laurent@814:         },
Laurent@814:         "reduce": GenerateFacetReducing("whiteSpace", True)
Laurent@814:     },
Laurent@814: 
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: #                       Syntax attributes definition
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: 
Laurent@814:     "abstract": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GetBoolean
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": False
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "attributeFormDefault": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateEnumeratedExtraction("member attributeFormDefault", ["qualified", "unqualified"])
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": "unqualified"
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "base": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member base", QName_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "block": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateGetList("block", ["restriction", "extension", "substitution"])
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "blockDefault": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateGetList("block", ["restriction", "extension", "substitution"])
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": ""
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "default": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GetAttributeValue
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "elementFormDefault": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateEnumeratedExtraction("member elementFormDefault", ["qualified", "unqualified"])
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": "unqualified"
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "final": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateGetList("final", ["restriction", "extension", "substitution"]),
Laurent@814:             "simpleType": GenerateGetList("final", ["list", "union", "restriction"])
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "finalDefault": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateGetList("finalDefault", ["restriction", "extension", "list", "union"])
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": ""
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "fixed": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GetBoolean,
Laurent@814:             "attribute": GetAttributeValue,
Laurent@814:             "element": GetAttributeValue
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": False,
Laurent@814:             "attribute": None,
Laurent@814:             "element": None
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "form": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateEnumeratedExtraction("member form", ["qualified", "unqualified"])
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "id": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member id", NCName_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "itemType": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member itemType", QName_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "memberTypes": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameListExtraction("member memberTypes", QNames_model)
Laurent@814:         },
Laurent@814:     },
Laurent@814:     
Laurent@814:     "maxOccurs": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateLimitExtraction(),
Laurent@814:             "all": GenerateLimitExtraction(1, 1, False)
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": 1
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "minOccurs": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateLimitExtraction(unbounded = False),
Laurent@814:             "all": GenerateLimitExtraction(0, 1, False)
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": 1
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "mixed": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GetBoolean
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": None,
Laurent@814:             "complexType": False
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "name": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member name", NCName_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "namespace": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member namespace", URI_model),
Laurent@814:             "any": GetNamespaces
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": None,
Laurent@814:             "any": "##any"
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "nillable": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GetBoolean
Laurent@814:         },
Laurent@814:     },
Laurent@814:     
Laurent@814:     "processContents": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateEnumeratedExtraction("member processContents", ["lax", "skip", "strict"])
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": "strict"
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "ref": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member ref", QName_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "refer": {
Laurent@814:         "type": SYNTAXATTRIBUTE,
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member refer", QName_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "schemaLocation": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member schemaLocation", URI_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "source": {
Laurent@814:         "type": SYNTAXATTRIBUTE,
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member source", URI_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "substitutionGroup": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member substitutionGroup", QName_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "targetNamespace": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member targetNamespace", URI_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814:     "type": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateModelNameExtraction("member type", QName_model)
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "use": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GenerateEnumeratedExtraction("member usage", ["required", "optional", "prohibited"])
Laurent@814:         },
Laurent@814:         "default": {
Laurent@814:             "default": "optional"
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "value": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814:             "default": GetAttributeValue,
Laurent@814:             "fractionDigits": GenerateIntegerExtraction(minInclusive=0),
Laurent@814:             "length": GenerateIntegerExtraction(minInclusive=0),
Laurent@814:             "maxLength": GenerateIntegerExtraction(minInclusive=0),
Laurent@814:             "minLength": GenerateIntegerExtraction(minInclusive=0),
Laurent@814:             "totalDigits": GenerateIntegerExtraction(minExclusive=0),
Laurent@814:             "whiteSpace": GenerateEnumeratedExtraction("value", ["collapse", "preserve", "replace"])
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "version": {
Laurent@814:         "type": SYNTAXATTRIBUTE,
Laurent@814:         "extract": {
Laurent@814:             "default": GetToken
Laurent@814:         }
Laurent@814:     },
Laurent@814: 
Laurent@814:     "xpath": {
Laurent@814:         "type": SYNTAXATTRIBUTE, 
Laurent@814:         "extract": {
Laurent@814: #            "default": NotSupportedYet("xpath")
Laurent@814:             "default": GetAttributeValue
Laurent@814:         }
Laurent@814:     },
Laurent@814:     
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: #                           Simple types definition
Laurent@814: #-------------------------------------------------------------------------------
Laurent@814: 
Laurent@814:     "string": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "string",
Laurent@814:         "extract": GetAttributeValue,
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x : x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "normalizedString": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "normalizedString",
Laurent@814:         "extract": GetNormalizedString,
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x : x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "token": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "token",  
Laurent@814:         "extract": GetToken,
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x : x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814:     
Laurent@814:     "base64Binary": {
Laurent@814:         "type": SIMPLETYPE, 
Laurent@814:         "basename": "base64Binary", 
Laurent@814:         "extract": NotSupportedYet("base64Binary"),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, (IntType, LongType))
Laurent@814:     },
Laurent@814:     
Laurent@814:     "hexBinary": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "hexBinary", 
Laurent@814:         "extract": GetHexInteger,
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: ("%."+str(int(round(len("%X"%x)/2.)*2))+"X")%x),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, (IntType, LongType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "integer": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "integer", 
Laurent@814:         "extract": GenerateIntegerExtraction(),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814:     
Laurent@814:     "positiveInteger": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "positiveInteger", 
Laurent@814:         "extract": GenerateIntegerExtraction(minExclusive=0),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@1078:         "initial": lambda: 1,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814:     
Laurent@814:     "negativeInteger": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "negativeInteger",
Laurent@814:         "extract": GenerateIntegerExtraction(maxExclusive=0),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@1078:         "initial": lambda: -1,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814:     
Laurent@814:     "nonNegativeInteger": {
Laurent@814:         "type": SIMPLETYPE, 
Laurent@814:         "basename": "nonNegativeInteger", 
Laurent@814:         "extract": GenerateIntegerExtraction(minInclusive=0),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814:     
Laurent@814:     "nonPositiveInteger": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "nonPositiveInteger", 
Laurent@814:         "extract": GenerateIntegerExtraction(maxInclusive=0),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814:     
Laurent@814:     "long": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "long",
Laurent@814:         "extract": GenerateIntegerExtraction(minInclusive=-2**63,maxExclusive=2**63),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814:     
Laurent@814:     "unsignedLong": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "unsignedLong",
Laurent@814:         "extract": GenerateIntegerExtraction(minInclusive=0,maxExclusive=2**64),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "int": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "int",
Laurent@814:         "extract": GenerateIntegerExtraction(minInclusive=-2**31,maxExclusive=2**31),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "unsignedInt": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "unsignedInt",
Laurent@814:         "extract": GenerateIntegerExtraction(minInclusive=0,maxExclusive=2**32),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "short": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "short",
Laurent@814:         "extract": GenerateIntegerExtraction(minInclusive=-2**15,maxExclusive=2**15),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "unsignedShort": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "unsignedShort", 
Laurent@814:         "extract": GenerateIntegerExtraction(minInclusive=0,maxExclusive=2**16),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "byte": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "byte",
Laurent@814:         "extract": GenerateIntegerExtraction(minInclusive=-2**7,maxExclusive=2**7),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "unsignedByte": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "unsignedByte",
Laurent@814:         "extract": GenerateIntegerExtraction(minInclusive=0,maxExclusive=2**8),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: 0,
Laurent@814:         "check": lambda x: isinstance(x, IntType)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "decimal": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "decimal",
Laurent@814:         "extract": GenerateFloatExtraction("decimal"),
Laurent@814:         "facets": DECIMAL_FACETS,
Laurent@1373:         "generate": GenerateFloatXMLText(decimal=3),
Laurent@814:         "initial": lambda: 0.,
Laurent@814:         "check": lambda x: isinstance(x, (IntType, FloatType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "float": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "float",
Laurent@814:         "extract": GenerateFloatExtraction("float", ["INF", "-INF", "NaN"]),
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateFloatXMLText(["INF", "-INF", "NaN"]),
Laurent@814:         "initial": lambda: 0.,
Laurent@814:         "check": lambda x: {"INF" : True, "-INF" : True, "NaN" : True}.get(x, isinstance(x, (IntType, FloatType)))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "double": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "double",
Laurent@814:         "extract": GenerateFloatExtraction("double", ["INF", "-INF", "NaN"]),
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateFloatXMLText(["INF", "-INF", "NaN"]),
Laurent@814:         "initial": lambda: 0.,
Laurent@814:         "check": lambda x: {"INF" : True, "-INF" : True, "NaN" : True}.get(x, isinstance(x, (IntType, FloatType)))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "boolean": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "boolean",
Laurent@814:         "extract": GetBoolean,
Laurent@814:         "facets": GenerateDictFacets(["pattern", "whiteSpace"]),
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x:{True : "true", False : "false"}[x]),
Laurent@814:         "initial": lambda: False,
Laurent@814:         "check": lambda x: isinstance(x, BooleanType)
Laurent@814:     },	
Laurent@814: 
Laurent@814:     "duration": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "duration",
Laurent@814:         "extract": NotSupportedYet("duration"),
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "dateTime": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "dateTime",
Laurent@814:         "extract": GetDateTime,
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(datetime.datetime.isoformat),
Laurent@814:         "initial": lambda: datetime.datetime(1,1,1,0,0,0,0),
Laurent@814:         "check": lambda x: isinstance(x, datetime.datetime)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "date": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "date",
Laurent@814:         "extract": GetDate,
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(datetime.date.isoformat),
Laurent@814:         "initial": lambda: datetime.date(1,1,1),
Laurent@814:         "check": lambda x: isinstance(x, datetime.date)
Laurent@814:     },
Laurent@814:     
Laurent@814:     "time": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "time",
Laurent@814:         "extract": GetTime,
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(datetime.time.isoformat),
Laurent@814:         "initial": lambda: datetime.time(0,0,0,0),
Laurent@814:         "check": lambda x: isinstance(x, datetime.time)
Laurent@814:     },
Laurent@814: 
Laurent@814:     "gYear": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "gYear",
Laurent@814:         "extract": NotSupportedYet("gYear"),
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "gYearMonth": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "gYearMonth",
Laurent@814:         "extract": NotSupportedYet("gYearMonth"),
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "gMonth": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "gMonth",
Laurent@814:         "extract": NotSupportedYet("gMonth"),
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "gMonthDay": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "gMonthDay",
Laurent@814:         "extract": NotSupportedYet("gMonthDay"),
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "gDay": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "gDay",
Laurent@814:         "extract": NotSupportedYet("gDay"),
Laurent@814:         "facets": NUMBER_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(str),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "Name": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "Name",
Laurent@814:         "extract": GenerateModelNameExtraction("Name", Name_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814:     
Laurent@814:     "QName": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "QName",
Laurent@814:         "extract": GenerateModelNameExtraction("QName", QName_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "NCName": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "NCName",
Laurent@814:         "extract": GenerateModelNameExtraction("NCName", NCName_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "anyURI": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "anyURI",
Laurent@814:         "extract": GenerateModelNameExtraction("anyURI", URI_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "language": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "language",
Laurent@814:         "extract": GenerateModelNameExtraction("language", LANGUAGE_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "en",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "ID": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "ID",
Laurent@814:         "extract": GenerateModelNameExtraction("ID", Name_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "IDREF": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "IDREF",
Laurent@814:         "extract": GenerateModelNameExtraction("IDREF", Name_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "IDREFS": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "IDREFS",
Laurent@814:         "extract": GenerateModelNameExtraction("IDREFS", Names_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "ENTITY": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "ENTITY",
Laurent@814:         "extract": GenerateModelNameExtraction("ENTITY", Name_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "ENTITIES": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "ENTITIES",
Laurent@814:         "extract": GenerateModelNameExtraction("ENTITIES", Names_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "NOTATION": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "NOTATION",
Laurent@814:         "extract": GenerateModelNameExtraction("NOTATION", Name_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "NMTOKEN": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "NMTOKEN",
Laurent@814:         "extract": GenerateModelNameExtraction("NMTOKEN", NMToken_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     "NMTOKENS": {
Laurent@814:         "type": SIMPLETYPE,
Laurent@814:         "basename": "NMTOKENS",
Laurent@814:         "extract": GenerateModelNameExtraction("NMTOKENS", NMTokens_model),
Laurent@814:         "facets": STRING_FACETS,
Laurent@814:         "generate": GenerateSimpleTypeXMLText(lambda x: x),
Laurent@814:         "initial": lambda: "",
Laurent@814:         "check": lambda x: isinstance(x, (StringType, UnicodeType))
Laurent@814:     },
Laurent@814: 
Laurent@814:     # Complex Types
Laurent@814:     "anyType": {"type": COMPLEXTYPE, "extract": lambda x:None},
Laurent@814: }
Laurent@814: