xmlclass/xsdschema.py
changeset 814 5743cbdff669
child 1078 f0ea86d830ed
equal deleted inserted replaced
813:1460273f40ed 814:5743cbdff669
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     5 #based on the plcopen standard. 
       
     6 #
       
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 #General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 import os, re
       
    26 import datetime
       
    27 from xml.dom import minidom
       
    28 from types import *
       
    29 
       
    30 from xmlclass import *
       
    31 
       
    32 def GenerateDictFacets(facets):
       
    33     return dict([(name, (None, False)) for name in facets])
       
    34 
       
    35 def GenerateSimpleTypeXMLText(function):
       
    36     def generateXMLTextMethod(value, name=None, indent=0):
       
    37         text = ""
       
    38         if name is not None:
       
    39             ind1, ind2 = getIndent(indent, name)
       
    40             text += ind1 + "<%s>" % name
       
    41         text += function(value)
       
    42         if name is not None:
       
    43             text += "</%s>\n" % name
       
    44         return text
       
    45     return generateXMLTextMethod
       
    46 
       
    47 def GenerateFloatXMLText(extra_values=[]):
       
    48     def generateXMLTextMethod(value, name=None, indent=0):
       
    49         text = ""
       
    50         if name is not None:
       
    51             ind1, ind2 = getIndent(indent, name)
       
    52             text += ind1 + "<%s>" % name
       
    53         if value in extra_values or value % 1 != 0 or isinstance(value, IntType):
       
    54             text += str(value)
       
    55         else:
       
    56             text += "%.0f" % value
       
    57         if name is not None:
       
    58             text += "</%s>\n" % name
       
    59         return text
       
    60     return generateXMLTextMethod
       
    61         
       
    62 DEFAULT_FACETS = GenerateDictFacets(["pattern", "whiteSpace", "enumeration"])
       
    63 NUMBER_FACETS = GenerateDictFacets(DEFAULT_FACETS.keys() + ["maxInclusive", "maxExclusive", "minInclusive", "minExclusive"])
       
    64 DECIMAL_FACETS = GenerateDictFacets(NUMBER_FACETS.keys() + ["totalDigits", "fractionDigits"])
       
    65 STRING_FACETS = GenerateDictFacets(DEFAULT_FACETS.keys() + ["length", "minLength", "maxLength"])
       
    66 
       
    67 ALL_FACETS = ["pattern", "whiteSpace", "enumeration", "maxInclusive", 
       
    68     "maxExclusive", "minInclusive", "minExclusive", "totalDigits", 
       
    69     "fractionDigits", "length", "minLength", "maxLength"]
       
    70 
       
    71 
       
    72 #-------------------------------------------------------------------------------
       
    73 #                           Structure reducing functions
       
    74 #-------------------------------------------------------------------------------
       
    75 
       
    76 
       
    77 # Documentation elements
       
    78 
       
    79 def ReduceAppInfo(factory, attributes, elements):
       
    80     return {"type": "appinfo", "source": attributes.get("source", None), 
       
    81             "content": "\n".join(elements)}
       
    82 
       
    83 
       
    84 def ReduceDocumentation(factory, attributes, elements):
       
    85     return {"type": "documentation", "source": attributes.get("source", None), 
       
    86             "language": attributes.get("lang", "any"), "content": "\n".join(elements)}
       
    87 
       
    88 
       
    89 def ReduceAnnotation(factory, attributes, elements):
       
    90     annotations, children = factory.ReduceElements(elements)
       
    91     annotation = {"type": "annotation", "appinfo": [], "documentation": {}}
       
    92     for child in children:
       
    93         if child["type"] == "appinfo":
       
    94             annotation["appinfo"].append((child["source"], child["content"]))
       
    95         elif child["type"] == "documentation":
       
    96             if child["source"] is not None:
       
    97                 text = "(source: %(source)s):\n%(content)s\n\n"%child
       
    98             else:
       
    99                 text = child["content"] + "\n\n"
       
   100             if not annotation["documentation"].has_key(child["language"]):
       
   101                 annotation["documentation"] = text
       
   102             else:
       
   103                 annotation["documentation"] += text
       
   104     return annotation
       
   105 
       
   106 # Simple type elements
       
   107 
       
   108 def GenerateFacetReducing(facetname, canbefixed):
       
   109     def ReduceFacet(factory, attributes, elements):
       
   110         annotations, children = factory.ReduceElements(elements)
       
   111         if attributes.has_key("value"):
       
   112             facet = {"type": facetname, "value": attributes["value"], "doc": annotations}
       
   113             if canbefixed:
       
   114                 facet["fixed"] = attributes.get("fixed", False)
       
   115             return facet
       
   116         raise ValueError("A value must be defined for the \"%s\" facet!" % facetname)
       
   117     return ReduceFacet
       
   118 
       
   119 
       
   120 def ReduceList(factory, attributes, elements):
       
   121     annotations, children = factory.ReduceElements(elements)
       
   122     list = {"type": "list", "itemType": attributes.get("itemType", None), "doc": annotations}
       
   123     
       
   124     if len(children) > 0 and children[0]["type"] == SIMPLETYPE:
       
   125         if list["itemType"] is None:
       
   126             list["itemType"] = children[0]
       
   127         else:
       
   128             raise ValueError("Only one base type can be defined for restriction!")
       
   129     if list["itemType"] is None:
       
   130         raise ValueError("No base type has been defined for list!")
       
   131     return list
       
   132 
       
   133 
       
   134 def ReduceUnion(factory, attributes, elements):
       
   135     annotations, children = factory.ReduceElements(elements)
       
   136     union = {"type": "union", "memberTypes": attributes.get("memberTypes", []), "doc": annotations}
       
   137     
       
   138     for child in children:
       
   139         if child["type"] == SIMPLETYPE:
       
   140             union["memberTypes"].appendchild
       
   141     if len(union["memberTypes"]) == 0:
       
   142         raise ValueError("No base type has been defined for union!")
       
   143     return union
       
   144 
       
   145 
       
   146 def CreateSimpleType(factory, attributes, typeinfos):
       
   147     # Initialize type informations
       
   148     facets = {}
       
   149     simpleType = {"type": SIMPLETYPE, "final": attributes.get("final", [])}
       
   150     if attributes.has_key("name"):
       
   151         simpleType["name"] = attributes["name"]
       
   152     
       
   153     if typeinfos["type"] in ["restriction", "extension"]:
       
   154         # Search for base type definition
       
   155         if isinstance(typeinfos["base"], (StringType, UnicodeType)):
       
   156             basetypeinfos = factory.FindSchemaElement(typeinfos["base"], SIMPLETYPE)
       
   157             if basetypeinfos is None:
       
   158                 raise "\"%s\" isn't defined!" % typeinfos["base"] 
       
   159         else:
       
   160             basetypeinfos = typeinfos["base"]
       
   161         
       
   162         # Check that base type is a simple type
       
   163         if basetypeinfos["type"] != SIMPLETYPE:
       
   164             raise ValueError("Base type given isn't a simpleType!")
       
   165         
       
   166         simpleType["basename"] = basetypeinfos["basename"]
       
   167         
       
   168         # Check that derivation is allowed
       
   169         if basetypeinfos.has_key("final"):
       
   170             if "#all" in basetypeinfos["final"]:
       
   171                 raise ValueError("Base type can't be derivated!")
       
   172             if "restriction" in basetypeinfos["final"] and typeinfos["type"] == "restriction":
       
   173                 raise ValueError("Base type can't be derivated by restriction!")
       
   174         
       
   175         # Extract simple type facets
       
   176         for facet in typeinfos.get("facets", []):
       
   177             facettype = facet["type"]
       
   178             if not basetypeinfos["facets"].has_key(facettype):
       
   179                 raise ValueError("\"%s\" facet can't be defined for \"%s\" type!" % (facettype, type))
       
   180             elif basetypeinfos["facets"][facettype][1]:
       
   181                 raise ValueError("\"%s\" facet is fixed on base type!" % facettype)
       
   182             value = facet["value"]
       
   183             basevalue = basetypeinfos["facets"][facettype][0]
       
   184             if facettype in ["enumeration", "pattern"]:
       
   185                 value = basetypeinfos["extract"](value, False)
       
   186                 if len(facets) == 0:
       
   187                     facets[facettype] = ([value], False)
       
   188                     continue
       
   189                 elif facets.keys() == [facettype]:
       
   190                     facets[facettype][0].append(value)
       
   191                     continue
       
   192                 else:
       
   193                     raise ValueError("\"%s\" facet can't be defined with another facet type!" % facettype)
       
   194             elif facets.has_key("enumeration"):
       
   195                 raise ValueError("\"enumeration\" facet can't be defined with another facet type!")
       
   196             elif facets.has_key("pattern"):
       
   197                 raise ValueError("\"pattern\" facet can't be defined with another facet type!")
       
   198             elif facets.has_key(facettype):
       
   199                 raise ValueError("\"%s\" facet can't be defined two times!" % facettype)
       
   200             elif facettype == "length":
       
   201                 if facets.has_key("minLength"):
       
   202                     raise ValueError("\"length\" and \"minLength\" facets can't be defined at the same time!")
       
   203                 if facets.has_key("maxLength"):
       
   204                     raise ValueError("\"length\" and \"maxLength\" facets can't be defined at the same time!")
       
   205                 try:
       
   206                     value = int(value)
       
   207                 except:
       
   208                     raise ValueError("\"length\" must be an integer!")
       
   209                 if value < 0:
       
   210                     raise ValueError("\"length\" can't be negative!")
       
   211                 elif basevalue is not None and basevalue != value:
       
   212                     raise ValueError("\"length\" can't be different from \"length\" defined in base type!")
       
   213             elif facettype == "minLength":
       
   214                 if facets.has_key("length"):
       
   215                     raise ValueError("\"length\" and \"minLength\" facets can't be defined at the same time!")
       
   216                 try:
       
   217                     value = int(value)
       
   218                 except:
       
   219                     raise ValueError("\"minLength\" must be an integer!")
       
   220                 if value < 0:
       
   221                     raise ValueError("\"minLength\" can't be negative!")
       
   222                 elif facets.has_key("maxLength") and value > facets["maxLength"]:
       
   223                     raise ValueError("\"minLength\" must be lesser than or equal to \"maxLength\"!")
       
   224                 elif basevalue is not None and basevalue < value:
       
   225                     raise ValueError("\"minLength\" can't be lesser than \"minLength\" defined in base type!")
       
   226             elif facettype == "maxLength":
       
   227                 if facets.has_key("length"):
       
   228                     raise ValueError("\"length\" and \"maxLength\" facets can't be defined at the same time!")
       
   229                 try:
       
   230                     value = int(value)
       
   231                 except:
       
   232                     raise ValueError("\"maxLength\" must be an integer!")
       
   233                 if value < 0:
       
   234                     raise ValueError("\"maxLength\" can't be negative!")
       
   235                 elif facets.has_key("minLength") and value < facets["minLength"]:
       
   236                     raise ValueError("\"minLength\" must be lesser than or equal to \"maxLength\"!")
       
   237                 elif basevalue is not None and basevalue > value:
       
   238                     raise ValueError("\"maxLength\" can't be greater than \"maxLength\" defined in base type!")
       
   239             elif facettype == "minInclusive":
       
   240                 if facets.has_key("minExclusive"):
       
   241                     raise ValueError("\"minExclusive\" and \"minInclusive\" facets can't be defined at the same time!")
       
   242                 value = basetypeinfos["extract"](facet["value"], False)
       
   243                 if facets.has_key("maxInclusive") and value > facets["maxInclusive"][0]:
       
   244                     raise ValueError("\"minInclusive\" must be lesser than or equal to \"maxInclusive\"!")
       
   245                 elif facets.has_key("maxExclusive") and value >= facets["maxExclusive"][0]:
       
   246                     raise ValueError("\"minInclusive\" must be lesser than \"maxExclusive\"!")
       
   247             elif facettype == "minExclusive":
       
   248                 if facets.has_key("minInclusive"):
       
   249                     raise ValueError("\"minExclusive\" and \"minInclusive\" facets can't be defined at the same time!")
       
   250                 value = basetypeinfos["extract"](facet["value"], False)
       
   251                 if facets.has_key("maxInclusive") and value >= facets["maxInclusive"][0]:
       
   252                     raise ValueError("\"minExclusive\" must be lesser than \"maxInclusive\"!")
       
   253                 elif facets.has_key("maxExclusive") and value >= facets["maxExclusive"][0]:
       
   254                     raise ValueError("\"minExclusive\" must be lesser than \"maxExclusive\"!")
       
   255             elif facettype == "maxInclusive":
       
   256                 if facets.has_key("maxExclusive"):
       
   257                     raise ValueError("\"maxExclusive\" and \"maxInclusive\" facets can't be defined at the same time!")
       
   258                 value = basetypeinfos["extract"](facet["value"], False)
       
   259                 if facets.has_key("minInclusive") and value < facets["minInclusive"][0]:
       
   260                     raise ValueError("\"minInclusive\" must be lesser than or equal to \"maxInclusive\"!")
       
   261                 elif facets.has_key("minExclusive") and value <= facets["minExclusive"][0]:
       
   262                     raise ValueError("\"minExclusive\" must be lesser than \"maxInclusive\"!")
       
   263             elif facettype == "maxExclusive":
       
   264                 if facets.has_key("maxInclusive"):
       
   265                     raise ValueError("\"maxExclusive\" and \"maxInclusive\" facets can't be defined at the same time!")
       
   266                 value = basetypeinfos["extract"](facet["value"], False)
       
   267                 if facets.has_key("minInclusive") and value <= facets["minInclusive"][0]:
       
   268                     raise ValueError("\"minInclusive\" must be lesser than \"maxExclusive\"!")
       
   269                 elif facets.has_key("minExclusive") and value <= facets["minExclusive"][0]:
       
   270                     raise ValueError("\"minExclusive\" must be lesser than \"maxExclusive\"!")
       
   271             elif facettype == "whiteSpace":
       
   272                 if basevalue == "collapse" and value in ["preserve", "replace"] or basevalue == "replace" and value == "preserve":
       
   273                    raise ValueError("\"whiteSpace\" is incompatible with \"whiteSpace\" defined in base type!")
       
   274             elif facettype == "totalDigits":
       
   275                 if facets.has_key("fractionDigits") and value <= facets["fractionDigits"][0]:
       
   276                     raise ValueError("\"fractionDigits\" must be lesser than or equal to \"totalDigits\"!")
       
   277                 elif basevalue is not None and value > basevalue:
       
   278                     raise ValueError("\"totalDigits\" can't be greater than \"totalDigits\" defined in base type!")
       
   279             elif facettype == "fractionDigits":
       
   280                 if facets.has_key("totalDigits") and value <= facets["totalDigits"][0]:
       
   281                     raise ValueError("\"fractionDigits\" must be lesser than or equal to \"totalDigits\"!")
       
   282                 elif basevalue is not None and value > basevalue:
       
   283                     raise ValueError("\"totalDigits\" can't be greater than \"totalDigits\" defined in base type!")
       
   284             facets[facettype] = (value, facet.get("fixed", False))
       
   285         
       
   286         # Report not redefined facet from base type to new created type 
       
   287         for facettype, facetvalue in basetypeinfos["facets"].items():
       
   288             if not facets.has_key(facettype):
       
   289                 facets[facettype] = facetvalue
       
   290         
       
   291         # Generate extract value for new created type
       
   292         def ExtractSimpleTypeValue(attr, extract=True):
       
   293             value = basetypeinfos["extract"](attr, extract)
       
   294             for facetname, (facetvalue, facetfixed) in facets.items():
       
   295                 if facetvalue is not None:
       
   296                     if facetname == "enumeration" and value not in facetvalue:
       
   297                         raise ValueError("\"%s\" not in enumerated values" % value)
       
   298                     elif facetname == "length" and len(value) != facetvalue:
       
   299                         raise ValueError("value must have a length of %d" % facetvalue)
       
   300                     elif facetname == "minLength" and len(value) < facetvalue:
       
   301                         raise ValueError("value must have a length of %d at least" % facetvalue)
       
   302                     elif facetname == "maxLength" and len(value) > facetvalue:
       
   303                         raise ValueError("value must have a length of %d at most" % facetvalue)
       
   304                     elif facetname == "minInclusive" and value < facetvalue:
       
   305                         raise ValueError("value must be greater than or equal to %s" % str(facetvalue))
       
   306                     elif facetname == "minExclusive" and value <= facetvalue:
       
   307                         raise ValueError("value must be greater than %s" % str(facetvalue))
       
   308                     elif facetname == "maxInclusive" and value > facetvalue:
       
   309                         raise ValueError("value must be lesser than or equal to %s" % str(facetvalue))
       
   310                     elif facetname == "maxExclusive"  and value >= facetvalue:
       
   311                         raise ValueError("value must be lesser than %s" % str(facetvalue))
       
   312                     elif facetname == "pattern":
       
   313                         model = re.compile("(?:%s)?$" % "|".join(map(lambda x: "(?:%s)" % x, facetvalue)))
       
   314                         result = model.match(value)
       
   315                         if result is None:
       
   316                             if len(facetvalue) > 1:   
       
   317                                 raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue))
       
   318                             else:
       
   319                                 raise ValueError("value doesn't follow the pattern %s" % facetvalue[0])
       
   320                     elif facetname == "whiteSpace":
       
   321                         if facetvalue == "replace":
       
   322                             value = GetNormalizedString(value, False)
       
   323                         elif facetvalue == "collapse":
       
   324                             value = GetToken(value, False)
       
   325             return value
       
   326         
       
   327         def CheckSimpleTypeValue(value):
       
   328             for facetname, (facetvalue, facetfixed) in facets.items():
       
   329                 if facetvalue is not None:
       
   330                     if facetname == "enumeration" and value not in facetvalue:
       
   331                         return False
       
   332                     elif facetname == "length" and len(value) != facetvalue:
       
   333                         return False
       
   334                     elif facetname == "minLength" and len(value) < facetvalue:
       
   335                         return False
       
   336                     elif facetname == "maxLength" and len(value) > facetvalue:
       
   337                         return False
       
   338                     elif facetname == "minInclusive" and value < facetvalue:
       
   339                         return False
       
   340                     elif facetname == "minExclusive" and value <= facetvalue:
       
   341                         return False
       
   342                     elif facetname == "maxInclusive" and value > facetvalue:
       
   343                         return False
       
   344                     elif facetname == "maxExclusive"  and value >= facetvalue:
       
   345                         return False
       
   346                     elif facetname == "pattern":
       
   347                         model = re.compile("(?:%s)?$" % "|".join(map(lambda x: "(?:%s)" % x, facetvalue)))
       
   348                         result = model.match(value)
       
   349                         if result is None:
       
   350                             if len(facetvalue) > 1:   
       
   351                                 raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue))
       
   352                             else:
       
   353                                 raise ValueError("value doesn't follow the pattern %s" % facetvalue[0])
       
   354             return True
       
   355         
       
   356         def SimpleTypeInitialValue():
       
   357             for facetname, (facetvalue, facetfixed) in facets.items():
       
   358                 if facetvalue is not None:
       
   359                     if facetname == "enumeration":
       
   360                         return facetvalue[0]
       
   361                     elif facetname == "length":
       
   362                         return " "*facetvalue
       
   363                     elif facetname == "minLength":
       
   364                         return " "*minLength
       
   365                     elif facetname == "minInclusive" and facetvalue > 0:
       
   366                         return facetvalue
       
   367                     elif facetname == "minExclusive" and facetvalue >= 0:
       
   368                         return facetvalue + 1
       
   369                     elif facetname == "maxInclusive" and facetvalue < 0:
       
   370                         return facetvalue
       
   371                     elif facetname == "maxExclusive"  and facetvalue <= 0:
       
   372                         return facetvalue - 1
       
   373             return basetypeinfos["initial"]()
       
   374         
       
   375         GenerateSimpleType = basetypeinfos["generate"]
       
   376         
       
   377     elif typeinfos["type"] == "list":
       
   378         # Search for item type definition
       
   379         if isinstance(typeinfos["itemType"], (StringType, UnicodeType)):
       
   380             itemtypeinfos = factory.FindSchemaElement(typeinfos["itemType"], SIMPLETYPE)
       
   381             if itemtypeinfos is None:
       
   382                 raise "\"%s\" isn't defined!" % typeinfos["itemType"]
       
   383         else:
       
   384             itemtypeinfos = typeinfos["itemType"]
       
   385         
       
   386         # Check that item type is a simple type
       
   387         if itemtypeinfos["type"] != SIMPLETYPE:
       
   388             raise ValueError, "Item type given isn't a simpleType!"
       
   389         
       
   390         simpleType["basename"] = "list"
       
   391         
       
   392         # Check that derivation is allowed
       
   393         if itemtypeinfos.has_key("final"):
       
   394             if itemtypeinfos["final"].has_key("#all"):
       
   395                 raise ValueError("Item type can't be derivated!")
       
   396             if itemtypeinfos["final"].has_key("list"):
       
   397                 raise ValueError("Item type can't be derivated by list!")
       
   398         
       
   399         # Generate extract value for new created type
       
   400         def ExtractSimpleTypeValue(attr, extract = True):
       
   401             values = []
       
   402             for value in GetToken(attr, extract).split(" "):
       
   403                 values.append(itemtypeinfos["extract"](value, False))
       
   404             return values
       
   405         
       
   406         def CheckSimpleTypeValue(value):
       
   407             for item in value:
       
   408                 result = itemtypeinfos["check"](item)
       
   409                 if not result:
       
   410                     return result
       
   411             return True
       
   412         
       
   413         SimpleTypeInitialValue = lambda: []
       
   414         
       
   415         GenerateSimpleType = GenerateSimpleTypeXMLText(lambda x: " ".join(map(itemtypeinfos["generate"], x)))
       
   416         
       
   417         facets = GenerateDictFacets(["length", "maxLength", "minLength", "enumeration", "pattern"])
       
   418         facets["whiteSpace"] = ("collapse", False)
       
   419     
       
   420     elif typeinfos["type"] == "union":
       
   421         # Search for member types definition
       
   422         membertypesinfos = []
       
   423         for membertype in typeinfos["memberTypes"]:
       
   424             if isinstance(membertype, (StringType, UnicodeType)):
       
   425                 infos = factory.FindSchemaElement(membertype, SIMPLETYPE)
       
   426                 if infos is None:
       
   427                     raise ValueError("\"%s\" isn't defined!" % membertype)
       
   428             else:
       
   429                 infos = membertype
       
   430             
       
   431             # Check that member type is a simple type
       
   432             if infos["type"] != SIMPLETYPE:
       
   433                 raise ValueError("Member type given isn't a simpleType!")
       
   434             
       
   435             # Check that derivation is allowed
       
   436             if infos.has_key("final"):
       
   437                 if infos["final"].has_key("#all"):
       
   438                     raise ValueError("Item type can't be derivated!")
       
   439                 if infos["final"].has_key("union"):
       
   440                     raise ValueError("Member type can't be derivated by union!")
       
   441             
       
   442             membertypesinfos.append(infos)
       
   443         
       
   444         simpleType["basename"] = "union"
       
   445         
       
   446         # Generate extract value for new created type
       
   447         def ExtractSimpleTypeValue(attr, extract = True):
       
   448             if extract:
       
   449                 value = GetAttributeValue(attr)
       
   450             else:
       
   451                 value = attr
       
   452             for infos in membertypesinfos:
       
   453                 try:
       
   454                     return infos["extract"](attr, False)
       
   455                 except:
       
   456                     pass
       
   457             raise ValueError("\"%s\" isn't valid for type defined for union!")
       
   458         
       
   459         def CheckSimpleTypeValue(value):
       
   460             for infos in membertypesinfos:
       
   461                 result = infos["check"](value)
       
   462                 if result:
       
   463                     return result
       
   464             return False
       
   465         
       
   466         SimpleTypeInitialValue = membertypesinfos[0]["initial"]
       
   467         
       
   468         def GenerateSimpleTypeFunction(value):
       
   469             if isinstance(value, BooleanType):
       
   470                 return {True: "true", False: "false"}[value]
       
   471             else:
       
   472                 return str(value)
       
   473         GenerateSimpleType = GenerateSimpleTypeXMLText(GenerateSimpleTypeFunction)
       
   474         
       
   475         facets = GenerateDictFacets(["pattern", "enumeration"])
       
   476     
       
   477     simpleType["facets"] = facets
       
   478     simpleType["extract"] = ExtractSimpleTypeValue
       
   479     simpleType["initial"] = SimpleTypeInitialValue
       
   480     simpleType["check"] = CheckSimpleTypeValue
       
   481     simpleType["generate"] = GenerateSimpleType
       
   482     return simpleType
       
   483 
       
   484 def ReduceSimpleType(factory, attributes, elements):
       
   485     # Reduce all the simple type children
       
   486     annotations, children = factory.ReduceElements(elements)
       
   487     
       
   488     simpleType = CreateSimpleType(factory, attributes, children[0])
       
   489     simpleType["doc"] = annotations
       
   490     
       
   491     return simpleType
       
   492 
       
   493 # Complex type
       
   494 
       
   495 def ExtractAttributes(factory, elements, base=None):
       
   496     attrs = []
       
   497     attrnames = {}
       
   498     if base is not None:
       
   499         basetypeinfos = factory.FindSchemaElement(base)
       
   500         if not isinstance(basetypeinfos, (UnicodeType, StringType)) and basetypeinfos["type"] == COMPLEXTYPE:
       
   501             attrnames = dict(map(lambda x:(x["name"], True), basetypeinfos["attributes"]))
       
   502         
       
   503     for element in elements:
       
   504         if element["type"] == ATTRIBUTE:
       
   505             if attrnames.get(element["name"], False):
       
   506                 raise ValueError("\"%s\" attribute has been defined two times!" % element["name"])
       
   507             else:
       
   508                 attrnames[element["name"]] = True
       
   509                 attrs.append(element)
       
   510         elif element["type"] == "attributeGroup":
       
   511             attrgroup = factory.FindSchemaElement(element["ref"], ATTRIBUTESGROUP)
       
   512             for attr in attrgroup["attributes"]:
       
   513                 if attrnames.get(attr["name"], False):
       
   514                     raise ValueError("\"%s\" attribute has been defined two times!" % attr["name"])
       
   515                 else:
       
   516                     attrnames[attr["name"]] = True
       
   517                     attrs.append(attr)
       
   518         elif element["type"] == "anyAttribute":
       
   519             raise ValueError("\"anyAttribute\" element isn't supported yet!")
       
   520     return attrs
       
   521 
       
   522 
       
   523 def ReduceRestriction(factory, attributes, elements):
       
   524     annotations, children = factory.ReduceElements(elements)
       
   525     restriction = {"type": "restriction", "base": attributes.get("base", None), "facets": [], "doc": annotations}
       
   526     if len(children) > 0 and children[0]["type"] == SIMPLETYPE:
       
   527         if restriction["base"] is None:
       
   528             restriction["base"] = children.pop(0)
       
   529         else:
       
   530             raise ValueError("Only one base type can be defined for restriction!")
       
   531     if restriction["base"] is None:
       
   532         raise ValueError("No base type has been defined for restriction!")
       
   533     
       
   534     while len(children) > 0 and children[0]["type"] in ALL_FACETS:
       
   535         restriction["facets"].append(children.pop(0))
       
   536     restriction["attributes"] = ExtractAttributes(factory, children, restriction["base"])
       
   537     return restriction
       
   538 
       
   539 
       
   540 def ReduceExtension(factory, attributes, elements):
       
   541     annotations, children = factory.ReduceElements(elements)
       
   542     if not attributes.has_key("base"):
       
   543         raise ValueError("No base type has been defined for extension!")
       
   544     extension = {"type": "extension", "attributes": [], "elements": [], "base": attributes["base"], "doc": annotations}
       
   545     if len(children) > 0:
       
   546         if children[0]["type"] in ["group", "all", CHOICE, "sequence"]:
       
   547             group = children.pop(0)
       
   548             if group["type"] in ["all", "sequence"]:
       
   549                 extension["elements"] = group["elements"]
       
   550                 extension["order"] = group["order"]
       
   551             elif group["type"] == CHOICE:
       
   552                 content = group.copy()
       
   553                 content["name"] = "content"
       
   554                 extension["elements"].append(content)
       
   555             elif group["type"] == "group":
       
   556                 elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP)
       
   557                 if elmtgroup.has_key("elements"):
       
   558                     extension["elements"] = elmtgroup["elements"]
       
   559                     extension["order"] = elmtgroup["order"]
       
   560                 else:
       
   561                     content = elmtgroup.copy()
       
   562                     content["name"] = "content"
       
   563                     extension["elements"].append(content)
       
   564         extension["attributes"] = ExtractAttributes(factory, children)
       
   565     return extension
       
   566 
       
   567 
       
   568 def ReduceSimpleContent(factory, attributes, elements):
       
   569     annotations, children = factory.ReduceElements(elements)
       
   570     
       
   571     simpleContent = children[0].copy()
       
   572     
       
   573     basetypeinfos = factory.FindSchemaElement(simpleContent["base"])
       
   574     if basetypeinfos["type"] == SIMPLETYPE:
       
   575         contenttypeinfos = simpleContent.copy()
       
   576         simpleContent.pop("base")
       
   577     elif basetypeinfos["type"] == COMPLEXTYPE and \
       
   578          len(basetypeinfos["elements"]) == 1 and \
       
   579          basetypeinfos["elements"][0]["name"] == "content" and \
       
   580          basetypeinfos["elements"][0].has_key("elmt_type") and \
       
   581          basetypeinfos["elements"][0]["elmt_type"]["type"] == SIMPLETYPE:
       
   582         contenttypeinfos = simpleContent.copy()
       
   583         contenttypeinfos["base"] = basetypeinfos["elements"][0]["elmt_type"]
       
   584     else:
       
   585         raise ValueError("No compatible base type defined for simpleContent!")
       
   586     contenttypeinfos = CreateSimpleType(factory, attributes, contenttypeinfos)
       
   587     
       
   588     simpleContent["elements"] = [{"name": "content", "type": ELEMENT,
       
   589                                   "elmt_type": contenttypeinfos, "doc": annotations,
       
   590                                   "minOccurs": 1, "maxOccurs": 1}]
       
   591     simpleContent["type"] = "simpleContent"
       
   592     return simpleContent
       
   593 
       
   594 
       
   595 def ReduceComplexContent(factory, attributes, elements):
       
   596     annotations, children = factory.ReduceElements(elements)
       
   597     complexContent = children[0].copy()
       
   598     complexContent["type"] = "complexContent"
       
   599     return complexContent
       
   600 
       
   601 
       
   602 def ReduceComplexType(factory, attributes, elements):
       
   603     annotations, children = factory.ReduceElements(elements)
       
   604     
       
   605     if len(children) > 0:
       
   606         if children[0]["type"] in ["simpleContent", "complexContent"]:
       
   607             complexType = children[0].copy()
       
   608             complexType.update(attributes)
       
   609             complexType["type"] = COMPLEXTYPE
       
   610             return complexType
       
   611         elif children[0]["type"] in ["group", "all", CHOICE, "sequence"]:
       
   612             complexType = {"type": COMPLEXTYPE, "elements": [], "order": True, "doc": annotations}
       
   613             complexType.update(attributes)
       
   614             group = children.pop(0)
       
   615             if group["type"] in ["all", "sequence"]:
       
   616                 choice_number = 0
       
   617                 for element in group["elements"]:
       
   618                     if element["type"] == CHOICE:
       
   619                         choice_number += 1
       
   620                 if (group["minOccurs"] == 0 or group["maxOccurs"] != 1) and len(group["elements"]) > 1 or choice_number > 1:
       
   621                     content = {"type": CHOICE, "name": "content", "choices": [group], "minOccurs": 1, "maxOccurs": 1}
       
   622                     complexType["elements"].append(content)
       
   623                 else:
       
   624                     if len(group["elements"]) == 1:
       
   625                         if group["minOccurs"] == 0:
       
   626                             group["elements"][0]["minOccurs"] = group["minOccurs"]
       
   627                         if group["maxOccurs"] != 1:
       
   628                             group["elements"][0]["maxOccurs"] = group["maxOccurs"]
       
   629                     for element in group["elements"]:
       
   630                         if element["type"] == CHOICE:
       
   631                             element["name"] = "content"
       
   632                     complexType["elements"] = group["elements"]
       
   633                     complexType["order"] = group["order"]
       
   634             elif group["type"] == CHOICE:
       
   635                 content = group.copy()
       
   636                 content["name"] = "content"
       
   637                 complexType["elements"].append(content)
       
   638             elif group["type"] == "group":
       
   639                 elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP)
       
   640                 if elmtgroup.has_key("elements"):
       
   641                     complexType["elements"] = elmtgroup["elements"]
       
   642                     complexType["order"] = elmtgroup["order"]
       
   643                 else:
       
   644                     content = elmtgroup.copy()
       
   645                     content["name"] = "content"
       
   646                     complexType["elements"].append(content)
       
   647         else:
       
   648             complexType = {"elements": [], "order": True, "doc": annotations}
       
   649             complexType.update(attributes)
       
   650             complexType["type"] = COMPLEXTYPE
       
   651         complexType["attributes"] = ExtractAttributes(factory, children)
       
   652         return complexType
       
   653     else:
       
   654         raise ValueError("\"ComplexType\" can't be empty!")
       
   655 
       
   656 
       
   657 # Attribute elements
       
   658 
       
   659 def ReduceAnyAttribute(factory, attributes, elements):
       
   660     return {"type" : "anyAttribute"}
       
   661 
       
   662 
       
   663 def ReduceAttribute(factory, attributes, elements):
       
   664     annotations, children = factory.ReduceElements(elements)
       
   665     
       
   666     if attributes.has_key("default"):
       
   667         if attributes.has_key("fixed"):
       
   668             raise ValueError("\"default\" and \"fixed\" can't be defined at the same time!")
       
   669         elif attributes.get("use", "optional") != "optional":
       
   670             raise ValueError("if \"default\" present, \"use\" can only have the value \"optional\"!")
       
   671     
       
   672     attribute = {"type": ATTRIBUTE, "attr_type": attributes.get("type", None), "doc": annotations}
       
   673     if len(children) > 0:
       
   674         if attribute["attr_type"] is None:
       
   675             attribute["attr_type"] = children[0]
       
   676         else:
       
   677             raise ValueError("Only one type can be defined for attribute!")
       
   678     
       
   679     if attributes.has_key("ref"):
       
   680         if attributes.has_key("name"):
       
   681             raise ValueError("\"ref\" and \"name\" can't be defined at the same time!")
       
   682         elif attributes.has_key("form"):
       
   683             raise ValueError("\"ref\" and \"form\" can't be defined at the same time!")
       
   684         elif attribute["attr_type"] is not None:
       
   685             raise ValueError("if \"ref\" is present, no type can be defined!")
       
   686     elif attribute["attr_type"] is None:
       
   687         raise ValueError("No type has been defined for attribute \"%s\"!" % attributes["name"])
       
   688     
       
   689     if attributes.has_key("type"):
       
   690         tmp_attrs = attributes.copy()
       
   691         tmp_attrs.pop("type")
       
   692         attribute.update(tmp_attrs)
       
   693     else:
       
   694         attribute.update(attributes)
       
   695     return attribute
       
   696 
       
   697 
       
   698 def ReduceAttributeGroup(factory, attributes, elements):
       
   699     annotations, children = factory.ReduceElements(elements)
       
   700     if attributes.has_key("ref"):
       
   701         return {"type": "attributeGroup", "ref": attributes["ref"], "doc": annotations}
       
   702     else:
       
   703         return {"type": ATTRIBUTESGROUP, "attributes": ExtractAttributes(factory, children), "doc": annotations}
       
   704 
       
   705 
       
   706 # Elements groups
       
   707 
       
   708 def ReduceAny(factory, attributes, elements):
       
   709     annotations, children = factory.ReduceElements(elements)
       
   710     
       
   711     any = {"type": ANY, "doc": annotations}
       
   712     any.update(attributes)
       
   713     return any
       
   714 
       
   715 def ReduceElement(factory, attributes, elements):
       
   716     annotations, children = factory.ReduceElements(elements)
       
   717     
       
   718     types = []
       
   719     constraints = []
       
   720     for child in children:
       
   721         if child["type"] == CONSTRAINT:
       
   722             constraints.append(child)
       
   723         else:
       
   724             types.append(child)
       
   725     
       
   726     if attributes.has_key("default") and attributes.has_key("fixed"):
       
   727         raise ValueError("\"default\" and \"fixed\" can't be defined at the same time!")
       
   728     
       
   729     if attributes.has_key("ref"):
       
   730         for attr in ["name", "default", "fixed", "form", "block", "type"]:
       
   731             if attributes.has_key(attr):
       
   732                 raise ValueError("\"ref\" and \"%s\" can't be defined at the same time!" % attr)
       
   733         if attributes.has_key("nillable"):
       
   734             raise ValueError("\"ref\" and \"nillable\" can't be defined at the same time!")
       
   735         if len(types) > 0:
       
   736             raise ValueError("No type and no constraints can be defined where \"ref\" is defined!")
       
   737     
       
   738         infos = factory.FindSchemaElement(attributes["ref"], ELEMENT)
       
   739         if infos is not None:
       
   740             element = infos.copy()
       
   741             element["constraints"] = constraints
       
   742             element["minOccurs"] = attributes["minOccurs"]
       
   743             element["maxOccurs"] = attributes["maxOccurs"]
       
   744             return element
       
   745         else:
       
   746             raise ValueError("\"%s\" base type isn't defined or circular referenced!" % name)
       
   747     
       
   748     elif attributes.has_key("name"):
       
   749         element = {"type": ELEMENT, "elmt_type": attributes.get("type", None), "constraints": constraints, "doc": annotations}
       
   750         if len(types) > 0:
       
   751             if element["elmt_type"] is None:
       
   752                 element["elmt_type"] = types[0]
       
   753             else:
       
   754                 raise ValueError("Only one type can be defined for attribute!")
       
   755         elif element["elmt_type"] is None:
       
   756             element["elmt_type"] = "tag"
       
   757             element["type"] = TAG
       
   758         
       
   759         if attributes.has_key("type"):
       
   760             tmp_attrs = attributes.copy()
       
   761             tmp_attrs.pop("type")
       
   762             element.update(tmp_attrs)
       
   763         else:
       
   764             element.update(attributes)
       
   765         return element
       
   766     else:
       
   767         raise ValueError("\"Element\" must have at least a \"ref\" or a \"name\" defined!")
       
   768 
       
   769 def ReduceAll(factory, attributes, elements):
       
   770     annotations, children = factory.ReduceElements(elements)
       
   771     
       
   772     for child in children:
       
   773         if children["maxOccurs"] == "unbounded" or children["maxOccurs"] > 1:
       
   774             raise ValueError("\"all\" item can't have \"maxOccurs\" attribute greater than 1!")
       
   775     
       
   776     return {"type": "all", "elements": children, "minOccurs": attributes["minOccurs"],
       
   777             "maxOccurs": attributes["maxOccurs"], "order": False, "doc": annotations}
       
   778 
       
   779 
       
   780 def ReduceChoice(factory, attributes, elements):
       
   781     annotations, children = factory.ReduceElements(elements)
       
   782     
       
   783     choices = []
       
   784     for child in children:
       
   785         if child["type"] in [ELEMENT, ANY, TAG]:
       
   786             choices.append(child)
       
   787         elif child["type"] == "sequence":
       
   788             child["minOccurs"] = child["maxOccurs"] = 1
       
   789             choices.append(child)
       
   790             #raise ValueError("\"sequence\" in \"choice\" is not supported. Create instead a new complex type!")
       
   791         elif child["type"] == CHOICE:
       
   792             choices.extend(child["choices"])
       
   793         elif child["type"] == "group":
       
   794             elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP) 
       
   795             if not elmtgroup.has_key("choices"):
       
   796                 raise ValueError("Only group composed of \"choice\" can be referenced in \"choice\" element!")
       
   797             choices_tmp = []
       
   798             for choice in elmtgroup["choices"]:
       
   799                 if not isinstance(choice["elmt_type"], (UnicodeType, StringType)) and choice["elmt_type"]["type"] == COMPLEXTYPE:
       
   800                     elmt_type = "%s_%s" % (elmtgroup["name"], choice["name"])
       
   801                     if factory.TargetNamespace is not None:
       
   802                         elmt_type = "%s:%s" % (factory.TargetNamespace, elmt_type)
       
   803                     new_choice = choice.copy()
       
   804                     new_choice["elmt_type"] = elmt_type
       
   805                     choices_tmp.append(new_choice)
       
   806                 else:
       
   807                     choices_tmp.append(choice)
       
   808             choices.extend(choices_tmp)
       
   809     
       
   810     for choice in choices:
       
   811         attributes["minOccurs"] = min(attributes["minOccurs"], choice["minOccurs"])
       
   812         choice["minOccurs"] = 1
       
   813     
       
   814     return {"type": CHOICE, "choices": choices, "minOccurs": attributes["minOccurs"],
       
   815             "maxOccurs": attributes["maxOccurs"], "doc": annotations}
       
   816 
       
   817 
       
   818 def ReduceSequence(factory, attributes, elements):
       
   819     annotations, children = factory.ReduceElements(elements)
       
   820     
       
   821     sequence = []
       
   822     for child in children:
       
   823         if child["type"] in [ELEMENT, ANY, TAG, CHOICE]:
       
   824             sequence.append(child)
       
   825         elif child["type"] == "sequence":
       
   826             sequence.extend(child["elements"])
       
   827         elif child["type"] == "group":
       
   828             elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP)
       
   829             if not elmtgroup.has_key("elements") or not elmtgroup["order"]:
       
   830                 raise ValueError("Only group composed of \"sequence\" can be referenced in \"sequence\" element!")
       
   831             elements_tmp = []
       
   832             for element in elmtgroup["elements"]:
       
   833                 if not isinstance(element["elmt_type"], (UnicodeType, StringType)) and element["elmt_type"]["type"] == COMPLEXTYPE:
       
   834                     elmt_type = "%s_%s"%(elmtgroup["name"], element["name"])
       
   835                     if factory.TargetNamespace is not None:
       
   836                         elmt_type = "%s:%s" % (factory.TargetNamespace, elmt_type)
       
   837                     new_element = element.copy()
       
   838                     new_element["elmt_type"] = elmt_type
       
   839                     elements_tmp.append(new_element)
       
   840                 else:
       
   841                     elements_tmp.append(element)
       
   842             sequence.extend(elements_tmp)
       
   843             
       
   844     return {"type": "sequence", "elements": sequence, "minOccurs": attributes["minOccurs"],
       
   845             "maxOccurs": attributes["maxOccurs"], "order": True, "doc": annotations}
       
   846     
       
   847     
       
   848 def ReduceGroup(factory, attributes, elements):
       
   849     annotations, children = factory.ReduceElements(elements)
       
   850     
       
   851     if attributes.has_key("ref"):
       
   852         return {"type": "group", "ref": attributes["ref"], "doc": annotations}
       
   853     else:
       
   854         element = children[0]
       
   855         group = {"type": ELEMENTSGROUP, "doc": annotations}
       
   856         if element["type"] == CHOICE:
       
   857             group["choices"] = element["choices"]
       
   858         else:
       
   859             group.update({"elements": element["elements"], "order": group["order"]})
       
   860         group.update(attributes)
       
   861         return group
       
   862 
       
   863 # Constraint elements
       
   864 
       
   865 def ReduceUnique(factory, attributes, elements):
       
   866     annotations, children = factory.ReduceElements(elements)
       
   867     
       
   868     unique = {"type": CONSTRAINT, "const_type": "unique", "selector": children[0], "fields": children[1:]}
       
   869     unique.update(attributes)
       
   870     return unique
       
   871     
       
   872 def ReduceKey(factory, attributes, elements):
       
   873     annotations, children = factory.ReduceElements(elements)
       
   874     
       
   875     key = {"type": CONSTRAINT, "const_type": "key", "selector": children[0], "fields": children[1:]}
       
   876     key.update(attributes)
       
   877     return key
       
   878 
       
   879 def ReduceKeyRef(factory, attributes, elements):
       
   880     annotations, children = factory.ReduceElements(elements)
       
   881     
       
   882     keyref = {"type": CONSTRAINT, "const_type": "keyref", "selector": children[0], "fields": children[1:]}
       
   883     keyref.update(attributes)
       
   884     return keyref
       
   885     
       
   886 def ReduceSelector(factory, attributes, elements):
       
   887     annotations, children = factory.ReduceElements(elements)
       
   888     
       
   889     selector = {"type": CONSTRAINT, "const_type": "selector"}
       
   890     selector.update(attributes)
       
   891     return selector
       
   892 
       
   893 def ReduceField(factory, attributes, elements):
       
   894     annotations, children = factory.ReduceElements(elements)
       
   895     
       
   896     field = {"type": CONSTRAINT, "const_type": "field"}
       
   897     field.update(attributes)
       
   898     return field
       
   899     
       
   900 
       
   901 # Inclusion elements
       
   902 
       
   903 def ReduceImport(factory, attributes, elements):
       
   904     annotations, children = factory.ReduceElements(elements)
       
   905     raise ValueError("\"import\" element isn't supported yet!")
       
   906 
       
   907 def ReduceInclude(factory, attributes, elements):
       
   908     annotations, children = factory.ReduceElements(elements)
       
   909     
       
   910     if factory.FileName is None:
       
   911         raise ValueError("Include in XSD string not yet supported")
       
   912     filepath = attributes["schemaLocation"]
       
   913     if filepath is not None and not os.path.exists(filepath):
       
   914         filepath = os.path.join(factory.BaseFolder, filepath)
       
   915         if not os.path.exists(filepath):
       
   916             raise ValueError("No file '%s' found for include" % attributes["schemaLocation"])
       
   917     xsdfile = open(filepath, 'r')
       
   918     include_factory = XSDClassFactory(minidom.parse(xsdfile), filepath)
       
   919     xsdfile.close()
       
   920     include_factory.CreateClasses()
       
   921     
       
   922     if factory.TargetNamespace == include_factory.TargetNamespace:
       
   923         factory.Namespaces[factory.TargetNamespace].update(include_factory.Namespaces[include_factory.TargetNamespace])
       
   924     else:
       
   925         factory.Namespaces[include_factory.TargetNamespace] = include_factory.Namespaces[include_factory.TargetNamespace]
       
   926     factory.ComputedClasses.update(include_factory.ComputedClasses)
       
   927     return None
       
   928     
       
   929 def ReduceRedefine(factory, attributes, elements):
       
   930     annotations, children = factory.ReduceElements(elements)
       
   931     raise ValueError("\"redefine\" element isn't supported yet!")
       
   932 
       
   933 
       
   934 # Schema element
       
   935 
       
   936 def ReduceSchema(factory, attributes, elements):
       
   937     factory.AttributeFormDefault = attributes["attributeFormDefault"]
       
   938     factory.ElementFormDefault = attributes["elementFormDefault"]
       
   939     factory.BlockDefault = attributes["blockDefault"]
       
   940     factory.FinalDefault = attributes["finalDefault"]
       
   941     
       
   942     if attributes.has_key("targetNamespace"):
       
   943         factory.TargetNamespace = factory.DefinedNamespaces.get(attributes["targetNamespace"], None)
       
   944     factory.Namespaces[factory.TargetNamespace] = {}
       
   945     
       
   946     annotations, children = factory.ReduceElements(elements, True)
       
   947     
       
   948     for child in children:
       
   949         if child.has_key("name"):
       
   950             infos = factory.GetQualifiedNameInfos(child["name"], factory.TargetNamespace, True)
       
   951             if infos is None:
       
   952                 factory.Namespaces[factory.TargetNamespace][child["name"]] = child
       
   953             elif not CompareSchema(infos, child):
       
   954                 raise ValueError("\"%s\" is defined twice in targetNamespace!" % child["name"])
       
   955 
       
   956 def CompareSchema(schema, reference):
       
   957     if isinstance(schema, ListType):
       
   958         if not isinstance(reference, ListType) or len(schema) != len(reference):
       
   959             return False
       
   960         for i, value in enumerate(schema):
       
   961             result = CompareSchema(value, reference[i])
       
   962             if not result:
       
   963                 return result
       
   964         return True
       
   965     elif isinstance(schema, DictType):
       
   966         if not isinstance(reference, DictType) or len(schema) != len(reference):
       
   967             return False
       
   968         for name, value in schema.items():
       
   969             ref_value = reference.get(name, None)
       
   970             if ref_value is None and value != None:
       
   971                 return False
       
   972             result = CompareSchema(value, ref_value)
       
   973             if not result:
       
   974                 return result
       
   975         return True
       
   976     elif isinstance(schema, FunctionType):
       
   977         if not isinstance(reference, FunctionType) or schema.__name__ != reference.__name__:
       
   978             return False
       
   979         else:
       
   980             return True
       
   981     return schema == reference
       
   982     
       
   983 #-------------------------------------------------------------------------------
       
   984 #                       Base class for XSD schema extraction
       
   985 #-------------------------------------------------------------------------------
       
   986 
       
   987 
       
   988 class XSDClassFactory(ClassFactory):
       
   989 
       
   990     def __init__(self, document, filepath=None, debug=False):
       
   991         ClassFactory.__init__(self, document, filepath, debug)
       
   992         self.Namespaces["xml"] = {
       
   993             "lang": {
       
   994                 "type": SYNTAXATTRIBUTE, 
       
   995                 "extract": {
       
   996                     "default": GenerateModelNameExtraction("lang", LANGUAGE_model)
       
   997                 }
       
   998             }
       
   999         }
       
  1000         self.Namespaces["xsi"] = {
       
  1001             "noNamespaceSchemaLocation": {
       
  1002                 "type": SYNTAXATTRIBUTE, 
       
  1003                 "extract": {
       
  1004                     "default": NotSupportedYet("noNamespaceSchemaLocation")
       
  1005                 }
       
  1006             },
       
  1007             "nil": {
       
  1008                 "type": SYNTAXATTRIBUTE, 
       
  1009                 "extract": {
       
  1010                     "default": NotSupportedYet("nil")
       
  1011                 }
       
  1012             },
       
  1013             "schemaLocation": {
       
  1014                 "type": SYNTAXATTRIBUTE, 
       
  1015                 "extract": {
       
  1016                     "default": NotSupportedYet("schemaLocation")
       
  1017                 }
       
  1018             },
       
  1019             "type": {
       
  1020                 "type": SYNTAXATTRIBUTE, 
       
  1021                 "extract": {
       
  1022                     "default": NotSupportedYet("type")
       
  1023                 }
       
  1024             }
       
  1025         }
       
  1026         
       
  1027     def ParseSchema(self):
       
  1028         for child in self.Document.childNodes:
       
  1029             if child.nodeType == self.Document.ELEMENT_NODE:
       
  1030                 schema = child
       
  1031                 break
       
  1032         for qualified_name, attr in schema._attrs.items():
       
  1033             value = GetAttributeValue(attr)
       
  1034             if value == "http://www.w3.org/2001/XMLSchema":
       
  1035                 namespace, name = DecomposeQualifiedName(qualified_name)
       
  1036                 if namespace == "xmlns":
       
  1037                     self.DefinedNamespaces["http://www.w3.org/2001/XMLSchema"] = name
       
  1038                     self.SchemaNamespace = name
       
  1039                 else:
       
  1040                     self.DefinedNamespaces["http://www.w3.org/2001/XMLSchema"] = self.SchemaNamespace
       
  1041                 self.Namespaces[self.SchemaNamespace] = XSD_NAMESPACE
       
  1042         self.Schema = XSD_NAMESPACE["schema"]["extract"]["default"](self, schema)
       
  1043         ReduceSchema(self, self.Schema[1], self.Schema[2])
       
  1044 
       
  1045     def FindSchemaElement(self, element_name, element_type=None):
       
  1046         namespace, name = DecomposeQualifiedName(element_name)
       
  1047         element = self.GetQualifiedNameInfos(name, namespace, True)
       
  1048         if element is None and namespace == self.TargetNamespace and name not in self.CurrentCompilations:
       
  1049             self.CurrentCompilations.append(name)
       
  1050             element = self.CreateSchemaElement(name, element_type)
       
  1051             self.CurrentCompilations.pop(-1)
       
  1052             if element is not None:
       
  1053                 self.Namespaces[self.TargetNamespace][name] = element
       
  1054         if element is None:
       
  1055             if name in self.CurrentCompilations:
       
  1056                 if self.Debug:
       
  1057                     print "Warning : \"%s\" is circular referenced!" % element_name
       
  1058             else:
       
  1059                 raise ValueError("\"%s\" isn't defined!" % element_name)
       
  1060         if element_type is not None and element["type"] != element_type:
       
  1061             raise ValueError("\"%s\" isn't of the expected type!" % element_name)
       
  1062         return element
       
  1063     
       
  1064     def CreateSchemaElement(self, element_name, element_type):
       
  1065         for type, attributes, elements in self.Schema[2]:
       
  1066             namespace, name = DecomposeQualifiedName(type)
       
  1067             if attributes.get("name", None) == element_name:
       
  1068                 element_infos = None
       
  1069                 if element_type in (ATTRIBUTE, None) and name == "attribute":
       
  1070                     element_infos = ReduceAttribute(self, attributes, elements)
       
  1071                 elif element_type in (ELEMENT, None) and name == "element":
       
  1072                     element_infos = ReduceElement(self, attributes, elements)
       
  1073                 elif element_type in (ATTRIBUTESGROUP, None) and name == "attributeGroup":
       
  1074                     element_infos = ReduceAttributeGroup(self, attributes, elements)
       
  1075                 elif element_type in (ELEMENTSGROUP, None) and name == "group":
       
  1076                     element_infos = ReduceGroup(self, attributes, elements)
       
  1077                 elif element_type in (SIMPLETYPE, None) and name == "simpleType":
       
  1078                     element_infos = ReduceSimpleType(self, attributes, elements)
       
  1079                 elif element_type in (COMPLEXTYPE, None) and name == "complexType":
       
  1080                     element_infos = ReduceComplexType(self, attributes, elements)
       
  1081                 if element_infos is not None:
       
  1082                     self.Namespaces[self.TargetNamespace][element_name] = element_infos
       
  1083                     return element_infos
       
  1084         return None
       
  1085 
       
  1086 """
       
  1087 This function opens the xsd file and generate the classes from the xml tree
       
  1088 """
       
  1089 def GenerateClassesFromXSD(filepath):
       
  1090     xsdfile = open(filepath, 'r')
       
  1091     factory = XSDClassFactory(minidom.parse(xsdfile), filepath)
       
  1092     xsdfile.close()
       
  1093     return GenerateClasses(factory)
       
  1094 
       
  1095 """
       
  1096 This function generate the classes from the xsd given as a string
       
  1097 """
       
  1098 def GenerateClassesFromXSDstring(xsdstring):
       
  1099     return GenerateClasses(XSDClassFactory(minidom.parseString(xsdstring)))
       
  1100 
       
  1101 
       
  1102 #-------------------------------------------------------------------------------
       
  1103 #                           XSD schema syntax elements
       
  1104 #-------------------------------------------------------------------------------
       
  1105 
       
  1106 XSD_NAMESPACE = {
       
  1107 
       
  1108 #-------------------------------------------------------------------------------
       
  1109 #                           Syntax elements definition
       
  1110 #-------------------------------------------------------------------------------
       
  1111 
       
  1112     "all": {"struct": """
       
  1113         <all
       
  1114           id = ID
       
  1115           maxOccurs = 1 : 1
       
  1116           minOccurs = (0 | 1) : 1
       
  1117           {any attributes with non-schema namespace . . .}>
       
  1118           Content: (annotation?, element*)
       
  1119         </all>""",
       
  1120         "type": SYNTAXELEMENT, 
       
  1121         "extract": {
       
  1122             "default": GenerateElement("all", ["id", "maxOccurs", "minOccurs"], 
       
  1123                 re.compile("((?:annotation )?(?:element )*)"))
       
  1124         },
       
  1125         "reduce": ReduceAll
       
  1126     },
       
  1127 
       
  1128     "annotation": {"struct": """
       
  1129         <annotation
       
  1130           id = ID
       
  1131           {any attributes with non-schema namespace . . .}>
       
  1132           Content: (appinfo | documentation)*
       
  1133         </annotation>""",
       
  1134         "type": SYNTAXELEMENT, 
       
  1135         "extract": {
       
  1136             "default": GenerateElement("annotation", ["id"], 
       
  1137                 re.compile("((?:app_info |documentation )*)"))
       
  1138         },
       
  1139         "reduce": ReduceAnnotation
       
  1140     },
       
  1141 
       
  1142     "any": {"struct": """
       
  1143         <any
       
  1144           id = ID
       
  1145           maxOccurs = (nonNegativeInteger | unbounded)  : 1
       
  1146           minOccurs = nonNegativeInteger : 1
       
  1147           namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
       
  1148           processContents = (lax | skip | strict) : strict
       
  1149           {any attributes with non-schema namespace . . .}>
       
  1150           Content: (annotation?)
       
  1151         </any>""",
       
  1152         "type": SYNTAXELEMENT, 
       
  1153         "extract": {
       
  1154             "default": GenerateElement("any", 
       
  1155                 ["id", "maxOccurs", "minOccurs", "namespace", "processContents"], 
       
  1156                 re.compile("((?:annotation )?(?:simpleType )*)"))
       
  1157         },
       
  1158         "reduce": ReduceAny
       
  1159     },
       
  1160 
       
  1161     "anyAttribute": {"struct": """
       
  1162         <anyAttribute
       
  1163           id = ID
       
  1164           namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
       
  1165           processContents = (lax | skip | strict) : strict
       
  1166           {any attributes with non-schema namespace . . .}>
       
  1167           Content: (annotation?)
       
  1168         </anyAttribute>""",
       
  1169         "type": SYNTAXELEMENT, 
       
  1170         "extract": {
       
  1171             "default": GenerateElement("anyAttribute",
       
  1172                 ["id", "namespace", "processContents"], ONLY_ANNOTATION)
       
  1173         },
       
  1174         "reduce": ReduceAnyAttribute
       
  1175     },
       
  1176 
       
  1177     "appinfo": {"struct": """
       
  1178         <appinfo
       
  1179           source = anyURI
       
  1180           {any attributes with non-schema namespace . . .}>
       
  1181           Content: ({any})*
       
  1182         </appinfo>""",
       
  1183         "type": SYNTAXELEMENT, 
       
  1184         "extract": {
       
  1185             "default": GenerateElement("appinfo", ["source"], re.compile("(.*)"), True)
       
  1186         },
       
  1187         "reduce": ReduceAppInfo
       
  1188     },
       
  1189 
       
  1190     "attribute": {"struct": """
       
  1191         <attribute
       
  1192           default = string
       
  1193           fixed = string
       
  1194           form = (qualified | unqualified)
       
  1195           id = ID
       
  1196           name = NCName
       
  1197           ref = QName
       
  1198           type = QName
       
  1199           use = (optional | prohibited | required) : optional
       
  1200           {any attributes with non-schema namespace . . .}>
       
  1201           Content: (annotation?, simpleType?)
       
  1202         </attribute>""",
       
  1203         "type": SYNTAXELEMENT, 
       
  1204         "extract": {
       
  1205             "default": GenerateElement("attribute", 
       
  1206                 ["default", "fixed", "form", "id", "name", "ref", "type", "use"], 
       
  1207                 re.compile("((?:annotation )?(?:simpleType )?)")),
       
  1208             "schema": GenerateElement("attribute", 
       
  1209                 ["default", "fixed", "form", "id", "name", "type"], 
       
  1210                 re.compile("((?:annotation )?(?:simpleType )?)"))
       
  1211         },
       
  1212         "reduce": ReduceAttribute
       
  1213     },
       
  1214 
       
  1215     "attributeGroup": {"struct": """
       
  1216         <attributeGroup
       
  1217           id = ID
       
  1218           name = NCName
       
  1219           ref = QName
       
  1220           {any attributes with non-schema namespace . . .}>
       
  1221           Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?))
       
  1222         </attributeGroup>""",
       
  1223         "type": SYNTAXELEMENT, 
       
  1224         "extract": {
       
  1225             "default": GenerateElement("attributeGroup", 
       
  1226                 ["id", "ref"], ONLY_ANNOTATION),
       
  1227             "schema": GenerateElement("attributeGroup",
       
  1228                 ["id", "name"], 
       
  1229                 re.compile("((?:annotation )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))"))
       
  1230         },
       
  1231         "reduce": ReduceAttributeGroup
       
  1232     },
       
  1233 
       
  1234     "choice": {"struct": """
       
  1235         <choice
       
  1236           id = ID
       
  1237           maxOccurs = (nonNegativeInteger | unbounded)  : 1
       
  1238           minOccurs = nonNegativeInteger : 1
       
  1239           {any attributes with non-schema namespace . . .}>
       
  1240           Content: (annotation?, (element | group | choice | sequence | any)*)
       
  1241         </choice>""",
       
  1242         "type": SYNTAXELEMENT, 
       
  1243         "extract": {
       
  1244             "default": GenerateElement("choice", ["id", "maxOccurs", "minOccurs"], 
       
  1245                 re.compile("((?:annotation )?(?:element |group |choice |sequence |any )*)"))
       
  1246         },
       
  1247         "reduce": ReduceChoice
       
  1248     },
       
  1249 
       
  1250     "complexContent": {"struct": """
       
  1251         <complexContent
       
  1252           id = ID
       
  1253           mixed = boolean
       
  1254           {any attributes with non-schema namespace . . .}>
       
  1255           Content: (annotation?, (restriction | extension))
       
  1256         </complexContent>""",
       
  1257         "type": SYNTAXELEMENT, 
       
  1258         "extract": {
       
  1259             "default": GenerateElement("complexContent", ["id", "mixed"], 
       
  1260                 re.compile("((?:annotation )?(?:restriction |extension ))"))
       
  1261         },
       
  1262         "reduce": ReduceComplexContent
       
  1263     },
       
  1264 
       
  1265     "complexType": {"struct": """
       
  1266         <complexType
       
  1267           abstract = boolean : false
       
  1268           block = (#all | List of (extension | restriction))
       
  1269           final = (#all | List of (extension | restriction))
       
  1270           id = ID
       
  1271           mixed = boolean : false
       
  1272           name = NCName
       
  1273           {any attributes with non-schema namespace . . .}>
       
  1274           Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
       
  1275         </complexType>""",
       
  1276         "type": SYNTAXELEMENT, 
       
  1277         "extract": {
       
  1278             "default": GenerateElement("complexType", 
       
  1279                 ["abstract", "block", "final", "id", "mixed", "name"], 
       
  1280                 re.compile("((?:annotation )?(?:simpleContent |complexContent |(?:(?:group |all |choice |sequence )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))))"))
       
  1281         },
       
  1282         "reduce": ReduceComplexType
       
  1283     },
       
  1284 
       
  1285     "documentation": {"struct" : """
       
  1286         <documentation
       
  1287           source = anyURI
       
  1288           xml:lang = language
       
  1289           {any attributes with non-schema namespace . . .}>
       
  1290           Content: ({any})*
       
  1291         </documentation>""",
       
  1292         "type": SYNTAXELEMENT, 
       
  1293         "extract": {
       
  1294             "default": GenerateElement("documentation", 
       
  1295                 ["source", "lang"], re.compile("(.*)"), True)
       
  1296         },
       
  1297         "reduce": ReduceDocumentation
       
  1298     },
       
  1299 
       
  1300     "element": {"struct": """
       
  1301         <element
       
  1302           abstract = boolean : false
       
  1303           block = (#all | List of (extension | restriction | substitution))
       
  1304           default = string
       
  1305           final = (#all | List of (extension | restriction))
       
  1306           fixed = string
       
  1307           form = (qualified | unqualified)
       
  1308           id = ID
       
  1309           maxOccurs = (nonNegativeInteger | unbounded)  : 1
       
  1310           minOccurs = nonNegativeInteger : 1
       
  1311           name = NCName
       
  1312           nillable = boolean : false
       
  1313           ref = QName
       
  1314           substitutionGroup = QName
       
  1315           type = QName
       
  1316           {any attributes with non-schema namespace . . .}>
       
  1317           Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
       
  1318         </element>""",
       
  1319         "type": SYNTAXELEMENT, 
       
  1320         "extract": {
       
  1321             "default": GenerateElement("element", 
       
  1322                 ["abstract", "block", "default", "final", "fixed", "form", "id", "maxOccurs", "minOccurs", "name", "nillable", "ref", "substitutionGroup", "type"], 
       
  1323                 re.compile("((?:annotation )?(?:simpleType |complexType )?(?:unique |key |keyref )*)")),
       
  1324             "schema": GenerateElement("element", 
       
  1325                 ["abstract", "block", "default", "final", "fixed", "form", "id", "name", "nillable", "substitutionGroup", "type"], 
       
  1326                 re.compile("((?:annotation )?(?:simpleType |complexType )?(?:unique |key |keyref )*)"))
       
  1327         },
       
  1328         "reduce": ReduceElement
       
  1329     },
       
  1330 
       
  1331     "enumeration": {"struct": """
       
  1332         <enumeration
       
  1333           id = ID
       
  1334           value = anySimpleType
       
  1335           {any attributes with non-schema namespace . . .}>
       
  1336           Content: (annotation?)
       
  1337         </enumeration>""",
       
  1338         "type": SYNTAXELEMENT, 
       
  1339         "extract": {
       
  1340             "default": GenerateElement("enumeration", ["id", "value"], ONLY_ANNOTATION)
       
  1341         },
       
  1342         "reduce": GenerateFacetReducing("enumeration", False)
       
  1343     },
       
  1344 
       
  1345     "extension": {"struct": """
       
  1346         <extension
       
  1347           base = QName
       
  1348           id = ID
       
  1349           {any attributes with non-schema namespace . . .}>
       
  1350           Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))
       
  1351         </extension>""",
       
  1352         "type": SYNTAXELEMENT, 
       
  1353         "extract": {
       
  1354             "default": GenerateElement("extension", ["base", "id"], 
       
  1355                 re.compile("((?:annotation )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))")),
       
  1356             "complexContent": GenerateElement("extension", ["base", "id"], 
       
  1357                 re.compile("((?:annotation )?(?:group |all |choice |sequence )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?))"))
       
  1358         },
       
  1359         "reduce": ReduceExtension
       
  1360     },
       
  1361 
       
  1362     "field": {"struct": """
       
  1363         <field
       
  1364           id = ID
       
  1365           xpath = a subset of XPath expression, see below
       
  1366           {any attributes with non-schema namespace . . .}>
       
  1367           Content: (annotation?)
       
  1368         </field>""",
       
  1369         "type": SYNTAXELEMENT, 
       
  1370         "extract": {
       
  1371             "default": GenerateElement("field", ["id", "xpath"], ONLY_ANNOTATION)
       
  1372         },
       
  1373         "reduce": ReduceField
       
  1374     },
       
  1375 
       
  1376     "fractionDigits": {"struct": """
       
  1377         <fractionDigits
       
  1378           fixed = boolean : false
       
  1379           id = ID
       
  1380           value = nonNegativeInteger
       
  1381           {any attributes with non-schema namespace . . .}>
       
  1382           Content: (annotation?)
       
  1383         </fractionDigits>""",
       
  1384         "type": SYNTAXELEMENT, 
       
  1385         "extract": {
       
  1386             "default": GenerateElement("fractionDigits", 
       
  1387                 ["fixed", "id", "value"], ONLY_ANNOTATION)
       
  1388         },
       
  1389         "reduce": GenerateFacetReducing("fractionDigits", True)
       
  1390     },
       
  1391 
       
  1392     "group": {"struct": """
       
  1393         <group
       
  1394           id = ID
       
  1395           maxOccurs = (nonNegativeInteger | unbounded)  : 1
       
  1396           minOccurs = nonNegativeInteger : 1
       
  1397           name = NCName
       
  1398           ref = QName
       
  1399           {any attributes with non-schema namespace . . .}>
       
  1400           Content: (annotation?, (all | choice | sequence)?)
       
  1401         </group>""",
       
  1402         "type": SYNTAXELEMENT, 
       
  1403         "extract": {
       
  1404             "default": GenerateElement("group",
       
  1405                 ["id", "maxOccurs", "minOccurs", "ref"], 
       
  1406                 re.compile("((?:annotation )?(?:all |choice |sequence )?)")),
       
  1407             "schema": GenerateElement("group",
       
  1408                 ["id", "name"], 
       
  1409                 re.compile("((?:annotation )?(?:all |choice |sequence )?)"))
       
  1410         },
       
  1411         "reduce": ReduceGroup
       
  1412     },
       
  1413 
       
  1414     "import": {"struct": """
       
  1415         <import
       
  1416           id = ID
       
  1417           namespace = anyURI
       
  1418           schemaLocation = anyURI
       
  1419           {any attributes with non-schema namespace . . .}>
       
  1420           Content: (annotation?)
       
  1421         </import>""",
       
  1422         "type": SYNTAXELEMENT, 
       
  1423         "extract": {
       
  1424             "default": GenerateElement("import",
       
  1425                 ["id", "namespace", "schemaLocation"], ONLY_ANNOTATION)
       
  1426         },
       
  1427         "reduce": ReduceImport
       
  1428     },
       
  1429 
       
  1430     "include": {"struct": """
       
  1431         <include
       
  1432           id = ID
       
  1433           schemaLocation = anyURI
       
  1434           {any attributes with non-schema namespace . . .}>
       
  1435           Content: (annotation?)
       
  1436         </include>""",
       
  1437         "type": SYNTAXELEMENT, 
       
  1438         "extract": {
       
  1439             "default": GenerateElement("include",
       
  1440                 ["id", "schemaLocation"], ONLY_ANNOTATION)
       
  1441         },
       
  1442         "reduce": ReduceInclude
       
  1443     },
       
  1444 
       
  1445     "key": {"struct": """
       
  1446         <key
       
  1447           id = ID
       
  1448           name = NCName
       
  1449           {any attributes with non-schema namespace . . .}>
       
  1450           Content: (annotation?, (selector, field+))
       
  1451         </key>""",
       
  1452         "type": SYNTAXELEMENT, 
       
  1453         "extract": {
       
  1454             "default": GenerateElement("key", ["id", "name"], 
       
  1455                 re.compile("((?:annotation )?(?:selector (?:field )+))"))
       
  1456         },
       
  1457         "reduce": ReduceKey
       
  1458     },
       
  1459 
       
  1460     "keyref": {"struct": """
       
  1461         <keyref
       
  1462           id = ID
       
  1463           name = NCName
       
  1464           refer = QName
       
  1465           {any attributes with non-schema namespace . . .}>
       
  1466           Content: (annotation?, (selector, field+))
       
  1467         </keyref>""",
       
  1468         "type": SYNTAXELEMENT, 
       
  1469         "extract": {
       
  1470             "default": GenerateElement("keyref", ["id", "name", "refer"], 
       
  1471                 re.compile("((?:annotation )?(?:selector (?:field )+))"))
       
  1472         },
       
  1473         "reduce": ReduceKeyRef
       
  1474     },
       
  1475 
       
  1476     "length": {"struct" : """
       
  1477         <length
       
  1478           fixed = boolean : false
       
  1479           id = ID
       
  1480           value = nonNegativeInteger
       
  1481           {any attributes with non-schema namespace . . .}>
       
  1482           Content: (annotation?)
       
  1483         </length>""",
       
  1484         "type": SYNTAXELEMENT, 
       
  1485         "extract": {
       
  1486             "default": GenerateElement("length", 
       
  1487                 ["fixed", "id", "value"], ONLY_ANNOTATION)
       
  1488         },
       
  1489         "reduce": GenerateFacetReducing("length", True)
       
  1490     },
       
  1491 
       
  1492     "list": {"struct": """
       
  1493         <list
       
  1494           id = ID
       
  1495           itemType = QName
       
  1496           {any attributes with non-schema namespace . . .}>
       
  1497           Content: (annotation?, simpleType?)
       
  1498         </list>""",
       
  1499         "type": SYNTAXELEMENT, 
       
  1500         "extract": {
       
  1501             "default": GenerateElement("list", ["id", "itemType"], 
       
  1502                 re.compile("((?:annotation )?(?:simpleType )?)$"))
       
  1503         },
       
  1504         "reduce": ReduceList
       
  1505     },
       
  1506 
       
  1507     "maxExclusive": {"struct": """
       
  1508         <maxInclusive
       
  1509           fixed = boolean : false
       
  1510           id = ID
       
  1511           value = anySimpleType
       
  1512           {any attributes with non-schema namespace . . .}>
       
  1513           Content: (annotation?)
       
  1514         </maxInclusive>""",
       
  1515         "type": SYNTAXELEMENT, 
       
  1516         "extract": {
       
  1517             "default": GenerateElement("maxExclusive",
       
  1518                 ["fixed", "id", "value"], ONLY_ANNOTATION)
       
  1519         },
       
  1520         "reduce": GenerateFacetReducing("maxExclusive", True)
       
  1521     },
       
  1522 
       
  1523     "maxInclusive": {"struct": """
       
  1524         <maxExclusive
       
  1525           fixed = boolean : false
       
  1526           id = ID
       
  1527           value = anySimpleType
       
  1528           {any attributes with non-schema namespace . . .}>
       
  1529           Content: (annotation?)
       
  1530         </maxExclusive>""",
       
  1531         "type": SYNTAXELEMENT, 
       
  1532         "extract": {
       
  1533             "default": GenerateElement("maxInclusive", 
       
  1534                 ["fixed", "id", "value"], ONLY_ANNOTATION)
       
  1535         },
       
  1536         "reduce": GenerateFacetReducing("maxInclusive", True)
       
  1537     },
       
  1538 
       
  1539     "maxLength": {"struct": """
       
  1540         <maxLength
       
  1541           fixed = boolean : false
       
  1542           id = ID
       
  1543           value = nonNegativeInteger
       
  1544           {any attributes with non-schema namespace . . .}>
       
  1545           Content: (annotation?)
       
  1546         </maxLength>""",
       
  1547         "type": SYNTAXELEMENT, 
       
  1548         "extract": {
       
  1549             "default": GenerateElement("maxLength", 
       
  1550                 ["fixed", "id", "value"], ONLY_ANNOTATION)
       
  1551         },
       
  1552         "reduce": GenerateFacetReducing("maxLength", True)
       
  1553     },
       
  1554 
       
  1555     "minExclusive": {"struct": """
       
  1556         <minExclusive
       
  1557           fixed = boolean : false
       
  1558           id = ID
       
  1559           value = anySimpleType
       
  1560           {any attributes with non-schema namespace . . .}>
       
  1561           Content: (annotation?)
       
  1562         </minExclusive>""",
       
  1563         "type": SYNTAXELEMENT, 
       
  1564         "extract": {
       
  1565             "default": GenerateElement("minExclusive", 
       
  1566                 ["fixed", "id", "value"], ONLY_ANNOTATION)
       
  1567         },
       
  1568         "reduce": GenerateFacetReducing("minExclusive", True)
       
  1569     },
       
  1570 
       
  1571     "minInclusive": {"struct": """
       
  1572         <minInclusive
       
  1573           fixed = boolean : false
       
  1574           id = ID
       
  1575           value = anySimpleType
       
  1576           {any attributes with non-schema namespace . . .}>
       
  1577           Content: (annotation?)
       
  1578         </minInclusive>""",
       
  1579         "type": SYNTAXELEMENT, 
       
  1580         "extract": {
       
  1581             "default": GenerateElement("minInclusive", 
       
  1582                 ["fixed", "id", "value"], ONLY_ANNOTATION)
       
  1583         },
       
  1584         "reduce": GenerateFacetReducing("minInclusive", True)
       
  1585     },
       
  1586 
       
  1587     "minLength": {"struct": """
       
  1588         <minLength
       
  1589           fixed = boolean : false
       
  1590           id = ID
       
  1591           value = nonNegativeInteger
       
  1592           {any attributes with non-schema namespace . . .}>
       
  1593           Content: (annotation?)
       
  1594         </minLength>""",
       
  1595         "type": SYNTAXELEMENT, 
       
  1596         "extract": {
       
  1597             "default": GenerateElement("minLength",
       
  1598                 ["fixed", "id", "value"], ONLY_ANNOTATION)
       
  1599         },
       
  1600         "reduce": GenerateFacetReducing("minLength", True)
       
  1601     },
       
  1602 
       
  1603     "pattern": {"struct": """
       
  1604         <pattern
       
  1605           id = ID
       
  1606           value = string
       
  1607           {any attributes with non-schema namespace . . .}>
       
  1608           Content: (annotation?)
       
  1609         </pattern>""",
       
  1610         "type": SYNTAXELEMENT, 
       
  1611         "extract": {
       
  1612             "default": GenerateElement("pattern", ["id", "value"], ONLY_ANNOTATION)
       
  1613         },
       
  1614         "reduce": GenerateFacetReducing("pattern", False)
       
  1615     },
       
  1616 
       
  1617     "redefine": {"struct": """
       
  1618         <redefine
       
  1619           id = ID
       
  1620           schemaLocation = anyURI
       
  1621           {any attributes with non-schema namespace . . .}>
       
  1622           Content: (annotation | (simpleType | complexType | group | attributeGroup))*
       
  1623         </redefine>""",
       
  1624         "type": SYNTAXELEMENT, 
       
  1625         "extract": {
       
  1626             "default": GenerateElement("refine", ["id", "schemaLocation"], 
       
  1627                 re.compile("((?:annotation |(?:simpleType |complexType |group |attributeGroup ))*)"))
       
  1628         },
       
  1629         "reduce": ReduceRedefine
       
  1630     },
       
  1631 
       
  1632     "restriction": {"struct": """
       
  1633         <restriction
       
  1634           base = QName
       
  1635           id = ID
       
  1636           {any attributes with non-schema namespace . . .}>
       
  1637           Content: (annotation?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))
       
  1638         </restriction>""",
       
  1639         "type": SYNTAXELEMENT, 
       
  1640         "extract": {
       
  1641             "default": GenerateElement("restriction", ["base", "id"], 
       
  1642                 re.compile("((?:annotation )?(?:(?:simpleType )?(?:(?:minExclusive |minInclusive |maxExclusive |maxInclusive |totalDigits |fractionDigits |length |minLength |maxLength |enumeration |whiteSpace |pattern )*)))")),
       
  1643             "simpleContent": GenerateElement("restriction", ["base", "id"], 
       
  1644                 re.compile("((?:annotation )?(?:(?:simpleType )?(?:(?:minExclusive |minInclusive |maxExclusive |maxInclusive |totalDigits |fractionDigits |length |minLength |maxLength |enumeration |whiteSpace |pattern )*)?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?)))")),
       
  1645             "complexContent": GenerateElement("restriction", ["base", "id"], 
       
  1646                 re.compile("((?:annotation )?(?:(?:simpleType )?(?:group |all |choice |sequence )?(?:(?:attribute |attributeGroup )*(?:anyAttribute )?)))")),
       
  1647         },
       
  1648         "reduce": ReduceRestriction
       
  1649     },
       
  1650 
       
  1651     "schema": {"struct": """
       
  1652         <schema
       
  1653           attributeFormDefault = (qualified | unqualified) : unqualified
       
  1654           blockDefault = (#all | List of (extension | restriction | substitution))  : ''
       
  1655           elementFormDefault = (qualified | unqualified) : unqualified
       
  1656           finalDefault = (#all | List of (extension | restriction | list | union))  : ''
       
  1657           id = ID
       
  1658           targetNamespace = anyURI
       
  1659           version = token
       
  1660           xml:lang = language
       
  1661           {any attributes with non-schema namespace . . .}>
       
  1662           Content: ((include | import | redefine | annotation)*, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*)
       
  1663         </schema>""",
       
  1664         "type": SYNTAXELEMENT, 
       
  1665         "extract": {
       
  1666             "default": GenerateElement("schema",
       
  1667                 ["attributeFormDefault", "blockDefault", "elementFormDefault", "finalDefault", "id", "targetNamespace", "version", "lang"], 
       
  1668                 re.compile("((?:include |import |redefine |annotation )*(?:(?:(?:simpleType |complexType |group |attributeGroup )|element |attribute |annotation )(?:annotation )*)*)"))
       
  1669         }
       
  1670     },
       
  1671 
       
  1672     "selector": {"struct": """
       
  1673         <selector
       
  1674           id = ID
       
  1675           xpath = a subset of XPath expression, see below
       
  1676           {any attributes with non-schema namespace . . .}>
       
  1677           Content: (annotation?)
       
  1678         </selector>""",
       
  1679         "type": SYNTAXELEMENT, 
       
  1680         "extract": {
       
  1681             "default": GenerateElement("selector", ["id", "xpath"], ONLY_ANNOTATION)
       
  1682         },
       
  1683         "reduce": ReduceSelector
       
  1684     },
       
  1685 
       
  1686     "sequence": {"struct": """
       
  1687         <sequence
       
  1688           id = ID
       
  1689           maxOccurs = (nonNegativeInteger | unbounded)  : 1
       
  1690           minOccurs = nonNegativeInteger : 1
       
  1691           {any attributes with non-schema namespace . . .}>
       
  1692           Content: (annotation?, (element | group | choice | sequence | any)*)
       
  1693         </sequence>""",
       
  1694         "type": SYNTAXELEMENT, 
       
  1695         "extract": {
       
  1696             "default": GenerateElement("sequence", ["id", "maxOccurs", "minOccurs"], 
       
  1697                 re.compile("((?:annotation )?(?:element |group |choice |sequence |any )*)"))
       
  1698         },
       
  1699         "reduce": ReduceSequence
       
  1700     },
       
  1701 
       
  1702     "simpleContent": {"struct" : """
       
  1703         <simpleContent
       
  1704           id = ID
       
  1705           {any attributes with non-schema namespace . . .}>
       
  1706           Content: (annotation?, (restriction | extension))
       
  1707         </simpleContent>""",
       
  1708         "type": SYNTAXELEMENT, 
       
  1709         "extract": {
       
  1710             "default": GenerateElement("simpleContent", ["id"], 
       
  1711                 re.compile("((?:annotation )?(?:restriction |extension ))"))
       
  1712         },
       
  1713         "reduce": ReduceSimpleContent
       
  1714     },
       
  1715 
       
  1716     "simpleType": {"struct" : """
       
  1717         <simpleType
       
  1718           final = (#all | List of (list | union | restriction))
       
  1719           id = ID
       
  1720           name = NCName
       
  1721           {any attributes with non-schema namespace . . .}>
       
  1722           Content: (annotation?, (restriction | list | union))
       
  1723         </simpleType>""",
       
  1724         "type": SYNTAXELEMENT, 
       
  1725         "extract": {
       
  1726             "default": GenerateElement("simpleType", ["final", "id", "name"], 
       
  1727                 re.compile("((?:annotation )?(?:restriction |list |union ))"))
       
  1728         },
       
  1729         "reduce": ReduceSimpleType
       
  1730     },
       
  1731 
       
  1732     "totalDigits": {"struct" : """
       
  1733         <totalDigits
       
  1734           fixed = boolean : false
       
  1735           id = ID
       
  1736           value = positiveInteger
       
  1737           {any attributes with non-schema namespace . . .}>
       
  1738           Content: (annotation?)
       
  1739         </totalDigits>""",
       
  1740         "type": SYNTAXELEMENT, 
       
  1741         "extract": {
       
  1742             "default": GenerateElement("totalDigits", 
       
  1743                 ["fixed", "id", "value"], ONLY_ANNOTATION),
       
  1744         },
       
  1745         "reduce": GenerateFacetReducing("totalDigits", True)
       
  1746     },
       
  1747 
       
  1748     "union": {"struct": """
       
  1749         <union
       
  1750           id = ID
       
  1751           memberTypes = List of QName
       
  1752           {any attributes with non-schema namespace . . .}>
       
  1753           Content: (annotation?, simpleType*)
       
  1754         </union>""",
       
  1755         "type": SYNTAXELEMENT, 
       
  1756         "extract": {
       
  1757             "default": GenerateElement("union", ["id", "memberTypes"], 
       
  1758                 re.compile("((?:annotation )?(?:simpleType )*)"))
       
  1759         },
       
  1760         "reduce": ReduceUnion
       
  1761     },
       
  1762 
       
  1763     "unique": {"struct": """
       
  1764         <unique
       
  1765           id = ID
       
  1766           name = NCName
       
  1767           {any attributes with non-schema namespace . . .}>
       
  1768           Content: (annotation?, (selector, field+))
       
  1769         </unique>""",
       
  1770         "type": SYNTAXELEMENT, 
       
  1771         "extract": {
       
  1772             "default": GenerateElement("unique", ["id", "name"], 
       
  1773                 re.compile("((?:annotation )?(?:selector |(?:field )+))"))
       
  1774         },
       
  1775         "reduce": ReduceUnique
       
  1776     },
       
  1777     
       
  1778     "whiteSpace": {"struct" : """
       
  1779         <whiteSpace
       
  1780           fixed = boolean : false
       
  1781           id = ID
       
  1782           value = (collapse | preserve | replace)
       
  1783           {any attributes with non-schema namespace . . .}>
       
  1784           Content: (annotation?)
       
  1785         </whiteSpace>""",
       
  1786         "type": SYNTAXELEMENT, 
       
  1787         "extract": {
       
  1788             "default": GenerateElement("whiteSpace", 
       
  1789                 ["fixed", "id", "value"], ONLY_ANNOTATION)
       
  1790         },
       
  1791         "reduce": GenerateFacetReducing("whiteSpace", True)
       
  1792     },
       
  1793 
       
  1794 #-------------------------------------------------------------------------------
       
  1795 #                       Syntax attributes definition
       
  1796 #-------------------------------------------------------------------------------
       
  1797 
       
  1798     "abstract": {
       
  1799         "type": SYNTAXATTRIBUTE, 
       
  1800         "extract": {
       
  1801             "default": GetBoolean
       
  1802         },
       
  1803         "default": {
       
  1804             "default": False
       
  1805         }
       
  1806     },
       
  1807 
       
  1808     "attributeFormDefault": {
       
  1809         "type": SYNTAXATTRIBUTE, 
       
  1810         "extract": {
       
  1811             "default": GenerateEnumeratedExtraction("member attributeFormDefault", ["qualified", "unqualified"])
       
  1812         },
       
  1813         "default": {
       
  1814             "default": "unqualified"
       
  1815         }
       
  1816     },
       
  1817     
       
  1818     "base": {
       
  1819         "type": SYNTAXATTRIBUTE, 
       
  1820         "extract": {
       
  1821             "default": GenerateModelNameExtraction("member base", QName_model)
       
  1822         }
       
  1823     },
       
  1824     
       
  1825     "block": {
       
  1826         "type": SYNTAXATTRIBUTE, 
       
  1827         "extract": {
       
  1828             "default": GenerateGetList("block", ["restriction", "extension", "substitution"])
       
  1829         }
       
  1830     },
       
  1831     
       
  1832     "blockDefault": {
       
  1833         "type": SYNTAXATTRIBUTE, 
       
  1834         "extract": {
       
  1835             "default": GenerateGetList("block", ["restriction", "extension", "substitution"])
       
  1836         },
       
  1837         "default": {
       
  1838             "default": ""
       
  1839         }
       
  1840     },
       
  1841     
       
  1842     "default": {
       
  1843         "type": SYNTAXATTRIBUTE, 
       
  1844         "extract": {
       
  1845             "default": GetAttributeValue
       
  1846         }
       
  1847     },
       
  1848 
       
  1849     "elementFormDefault": {
       
  1850         "type": SYNTAXATTRIBUTE, 
       
  1851         "extract": {
       
  1852             "default": GenerateEnumeratedExtraction("member elementFormDefault", ["qualified", "unqualified"])
       
  1853         },
       
  1854         "default": {
       
  1855             "default": "unqualified"
       
  1856         }
       
  1857     },
       
  1858     
       
  1859     "final": {
       
  1860         "type": SYNTAXATTRIBUTE, 
       
  1861         "extract": {
       
  1862             "default": GenerateGetList("final", ["restriction", "extension", "substitution"]),
       
  1863             "simpleType": GenerateGetList("final", ["list", "union", "restriction"])
       
  1864         }
       
  1865     },
       
  1866 
       
  1867     "finalDefault": {
       
  1868         "type": SYNTAXATTRIBUTE, 
       
  1869         "extract": {
       
  1870             "default": GenerateGetList("finalDefault", ["restriction", "extension", "list", "union"])
       
  1871         },
       
  1872         "default": {
       
  1873             "default": ""
       
  1874         }
       
  1875     },
       
  1876     
       
  1877     "fixed": {
       
  1878         "type": SYNTAXATTRIBUTE, 
       
  1879         "extract": {
       
  1880             "default": GetBoolean,
       
  1881             "attribute": GetAttributeValue,
       
  1882             "element": GetAttributeValue
       
  1883         },
       
  1884         "default": {
       
  1885             "default": False,
       
  1886             "attribute": None,
       
  1887             "element": None
       
  1888         }
       
  1889     },
       
  1890 
       
  1891     "form": {
       
  1892         "type": SYNTAXATTRIBUTE, 
       
  1893         "extract": {
       
  1894             "default": GenerateEnumeratedExtraction("member form", ["qualified", "unqualified"])
       
  1895         }
       
  1896     },
       
  1897 
       
  1898     "id": {
       
  1899         "type": SYNTAXATTRIBUTE, 
       
  1900         "extract": {
       
  1901             "default": GenerateModelNameExtraction("member id", NCName_model)
       
  1902         }
       
  1903     },
       
  1904     
       
  1905     "itemType": {
       
  1906         "type": SYNTAXATTRIBUTE, 
       
  1907         "extract": {
       
  1908             "default": GenerateModelNameExtraction("member itemType", QName_model)
       
  1909         }
       
  1910     },
       
  1911 
       
  1912     "memberTypes": {
       
  1913         "type": SYNTAXATTRIBUTE, 
       
  1914         "extract": {
       
  1915             "default": GenerateModelNameListExtraction("member memberTypes", QNames_model)
       
  1916         },
       
  1917     },
       
  1918     
       
  1919     "maxOccurs": {
       
  1920         "type": SYNTAXATTRIBUTE, 
       
  1921         "extract": {
       
  1922             "default": GenerateLimitExtraction(),
       
  1923             "all": GenerateLimitExtraction(1, 1, False)
       
  1924         },
       
  1925         "default": {
       
  1926             "default": 1
       
  1927         }
       
  1928     },
       
  1929 
       
  1930     "minOccurs": {
       
  1931         "type": SYNTAXATTRIBUTE, 
       
  1932         "extract": {
       
  1933             "default": GenerateLimitExtraction(unbounded = False),
       
  1934             "all": GenerateLimitExtraction(0, 1, False)
       
  1935         },
       
  1936         "default": {
       
  1937             "default": 1
       
  1938         }
       
  1939     },
       
  1940 
       
  1941     "mixed": {
       
  1942         "type": SYNTAXATTRIBUTE, 
       
  1943         "extract": {
       
  1944             "default": GetBoolean
       
  1945         },
       
  1946         "default": {
       
  1947             "default": None,
       
  1948             "complexType": False
       
  1949         }
       
  1950     },
       
  1951     
       
  1952     "name": {
       
  1953         "type": SYNTAXATTRIBUTE, 
       
  1954         "extract": {
       
  1955             "default": GenerateModelNameExtraction("member name", NCName_model)
       
  1956         }
       
  1957     },
       
  1958     
       
  1959     "namespace": {
       
  1960         "type": SYNTAXATTRIBUTE, 
       
  1961         "extract": {
       
  1962             "default": GenerateModelNameExtraction("member namespace", URI_model),
       
  1963             "any": GetNamespaces
       
  1964         },
       
  1965         "default": {
       
  1966             "default": None,
       
  1967             "any": "##any"
       
  1968         }
       
  1969     },
       
  1970 
       
  1971     "nillable": {
       
  1972         "type": SYNTAXATTRIBUTE, 
       
  1973         "extract": {
       
  1974             "default": GetBoolean
       
  1975         },
       
  1976     },
       
  1977     
       
  1978     "processContents": {
       
  1979         "type": SYNTAXATTRIBUTE, 
       
  1980         "extract": {
       
  1981             "default": GenerateEnumeratedExtraction("member processContents", ["lax", "skip", "strict"])
       
  1982         },
       
  1983         "default": {
       
  1984             "default": "strict"
       
  1985         }
       
  1986     },
       
  1987     
       
  1988     "ref": {
       
  1989         "type": SYNTAXATTRIBUTE, 
       
  1990         "extract": {
       
  1991             "default": GenerateModelNameExtraction("member ref", QName_model)
       
  1992         }
       
  1993     },
       
  1994 
       
  1995     "refer": {
       
  1996         "type": SYNTAXATTRIBUTE,
       
  1997         "extract": {
       
  1998             "default": GenerateModelNameExtraction("member refer", QName_model)
       
  1999         }
       
  2000     },
       
  2001     
       
  2002     "schemaLocation": {
       
  2003         "type": SYNTAXATTRIBUTE, 
       
  2004         "extract": {
       
  2005             "default": GenerateModelNameExtraction("member schemaLocation", URI_model)
       
  2006         }
       
  2007     },
       
  2008     
       
  2009     "source": {
       
  2010         "type": SYNTAXATTRIBUTE,
       
  2011         "extract": {
       
  2012             "default": GenerateModelNameExtraction("member source", URI_model)
       
  2013         }
       
  2014     },
       
  2015     
       
  2016     "substitutionGroup": {
       
  2017         "type": SYNTAXATTRIBUTE, 
       
  2018         "extract": {
       
  2019             "default": GenerateModelNameExtraction("member substitutionGroup", QName_model)
       
  2020         }
       
  2021     },
       
  2022 
       
  2023     "targetNamespace": {
       
  2024         "type": SYNTAXATTRIBUTE, 
       
  2025         "extract": {
       
  2026             "default": GenerateModelNameExtraction("member targetNamespace", URI_model)
       
  2027         }
       
  2028     },
       
  2029     
       
  2030     "type": {
       
  2031         "type": SYNTAXATTRIBUTE, 
       
  2032         "extract": {
       
  2033             "default": GenerateModelNameExtraction("member type", QName_model)
       
  2034         }
       
  2035     },
       
  2036 
       
  2037     "use": {
       
  2038         "type": SYNTAXATTRIBUTE, 
       
  2039         "extract": {
       
  2040             "default": GenerateEnumeratedExtraction("member usage", ["required", "optional", "prohibited"])
       
  2041         },
       
  2042         "default": {
       
  2043             "default": "optional"
       
  2044         }
       
  2045     },
       
  2046 
       
  2047     "value": {
       
  2048         "type": SYNTAXATTRIBUTE, 
       
  2049         "extract": {
       
  2050             "default": GetAttributeValue,
       
  2051             "fractionDigits": GenerateIntegerExtraction(minInclusive=0),
       
  2052             "length": GenerateIntegerExtraction(minInclusive=0),
       
  2053             "maxLength": GenerateIntegerExtraction(minInclusive=0),
       
  2054             "minLength": GenerateIntegerExtraction(minInclusive=0),
       
  2055             "totalDigits": GenerateIntegerExtraction(minExclusive=0),
       
  2056             "whiteSpace": GenerateEnumeratedExtraction("value", ["collapse", "preserve", "replace"])
       
  2057         }
       
  2058     },
       
  2059 
       
  2060     "version": {
       
  2061         "type": SYNTAXATTRIBUTE,
       
  2062         "extract": {
       
  2063             "default": GetToken
       
  2064         }
       
  2065     },
       
  2066 
       
  2067     "xpath": {
       
  2068         "type": SYNTAXATTRIBUTE, 
       
  2069         "extract": {
       
  2070 #            "default": NotSupportedYet("xpath")
       
  2071             "default": GetAttributeValue
       
  2072         }
       
  2073     },
       
  2074     
       
  2075 #-------------------------------------------------------------------------------
       
  2076 #                           Simple types definition
       
  2077 #-------------------------------------------------------------------------------
       
  2078 
       
  2079     "string": {
       
  2080         "type": SIMPLETYPE,
       
  2081         "basename": "string",
       
  2082         "extract": GetAttributeValue,
       
  2083         "facets": STRING_FACETS,
       
  2084         "generate": GenerateSimpleTypeXMLText(lambda x : x),
       
  2085         "initial": lambda: "",
       
  2086         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2087     },
       
  2088 
       
  2089     "normalizedString": {
       
  2090         "type": SIMPLETYPE,
       
  2091         "basename": "normalizedString",
       
  2092         "extract": GetNormalizedString,
       
  2093         "facets": STRING_FACETS,
       
  2094         "generate": GenerateSimpleTypeXMLText(lambda x : x),
       
  2095         "initial": lambda: "",
       
  2096         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2097     },
       
  2098 
       
  2099     "token": {
       
  2100         "type": SIMPLETYPE,
       
  2101         "basename": "token",  
       
  2102         "extract": GetToken,
       
  2103         "facets": STRING_FACETS,
       
  2104         "generate": GenerateSimpleTypeXMLText(lambda x : x),
       
  2105         "initial": lambda: "",
       
  2106         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2107     },
       
  2108     
       
  2109     "base64Binary": {
       
  2110         "type": SIMPLETYPE, 
       
  2111         "basename": "base64Binary", 
       
  2112         "extract": NotSupportedYet("base64Binary"),
       
  2113         "facets": STRING_FACETS,
       
  2114         "generate": GenerateSimpleTypeXMLText(str),
       
  2115         "initial": lambda: 0,
       
  2116         "check": lambda x: isinstance(x, (IntType, LongType))
       
  2117     },
       
  2118     
       
  2119     "hexBinary": {
       
  2120         "type": SIMPLETYPE,
       
  2121         "basename": "hexBinary", 
       
  2122         "extract": GetHexInteger,
       
  2123         "facets": STRING_FACETS,
       
  2124         "generate": GenerateSimpleTypeXMLText(lambda x: ("%."+str(int(round(len("%X"%x)/2.)*2))+"X")%x),
       
  2125         "initial": lambda: 0,
       
  2126         "check": lambda x: isinstance(x, (IntType, LongType))
       
  2127     },
       
  2128 
       
  2129     "integer": {
       
  2130         "type": SIMPLETYPE,
       
  2131         "basename": "integer", 
       
  2132         "extract": GenerateIntegerExtraction(),
       
  2133         "facets": DECIMAL_FACETS,
       
  2134         "generate": GenerateSimpleTypeXMLText(str),
       
  2135         "initial": lambda: 0,
       
  2136         "check": lambda x: isinstance(x, IntType)
       
  2137     },
       
  2138     
       
  2139     "positiveInteger": {
       
  2140         "type": SIMPLETYPE,
       
  2141         "basename": "positiveInteger", 
       
  2142         "extract": GenerateIntegerExtraction(minExclusive=0),
       
  2143         "facets": DECIMAL_FACETS,
       
  2144         "generate": GenerateSimpleTypeXMLText(str),
       
  2145         "initial": lambda: 0,
       
  2146         "check": lambda x: isinstance(x, IntType)
       
  2147     },
       
  2148     
       
  2149     "negativeInteger": {
       
  2150         "type": SIMPLETYPE,
       
  2151         "basename": "negativeInteger",
       
  2152         "extract": GenerateIntegerExtraction(maxExclusive=0),
       
  2153         "facets": DECIMAL_FACETS,
       
  2154         "generate": GenerateSimpleTypeXMLText(str),
       
  2155         "initial": lambda: 0,
       
  2156         "check": lambda x: isinstance(x, IntType)
       
  2157     },
       
  2158     
       
  2159     "nonNegativeInteger": {
       
  2160         "type": SIMPLETYPE, 
       
  2161         "basename": "nonNegativeInteger", 
       
  2162         "extract": GenerateIntegerExtraction(minInclusive=0),
       
  2163         "facets": DECIMAL_FACETS,
       
  2164         "generate": GenerateSimpleTypeXMLText(str),
       
  2165         "initial": lambda: 0,
       
  2166         "check": lambda x: isinstance(x, IntType)
       
  2167     },
       
  2168     
       
  2169     "nonPositiveInteger": {
       
  2170         "type": SIMPLETYPE,
       
  2171         "basename": "nonPositiveInteger", 
       
  2172         "extract": GenerateIntegerExtraction(maxInclusive=0),
       
  2173         "facets": DECIMAL_FACETS,
       
  2174         "generate": GenerateSimpleTypeXMLText(str),
       
  2175         "initial": lambda: 0,
       
  2176         "check": lambda x: isinstance(x, IntType)
       
  2177     },
       
  2178     
       
  2179     "long": {
       
  2180         "type": SIMPLETYPE,
       
  2181         "basename": "long",
       
  2182         "extract": GenerateIntegerExtraction(minInclusive=-2**63,maxExclusive=2**63),
       
  2183         "facets": DECIMAL_FACETS,
       
  2184         "generate": GenerateSimpleTypeXMLText(str),
       
  2185         "initial": lambda: 0,
       
  2186         "check": lambda x: isinstance(x, IntType)
       
  2187     },
       
  2188     
       
  2189     "unsignedLong": {
       
  2190         "type": SIMPLETYPE,
       
  2191         "basename": "unsignedLong",
       
  2192         "extract": GenerateIntegerExtraction(minInclusive=0,maxExclusive=2**64),
       
  2193         "facets": DECIMAL_FACETS,
       
  2194         "generate": GenerateSimpleTypeXMLText(str),
       
  2195         "initial": lambda: 0,
       
  2196         "check": lambda x: isinstance(x, IntType)
       
  2197     },
       
  2198 
       
  2199     "int": {
       
  2200         "type": SIMPLETYPE,
       
  2201         "basename": "int",
       
  2202         "extract": GenerateIntegerExtraction(minInclusive=-2**31,maxExclusive=2**31),
       
  2203         "facets": DECIMAL_FACETS,
       
  2204         "generate": GenerateSimpleTypeXMLText(str),
       
  2205         "initial": lambda: 0,
       
  2206         "check": lambda x: isinstance(x, IntType)
       
  2207     },
       
  2208 
       
  2209     "unsignedInt": {
       
  2210         "type": SIMPLETYPE,
       
  2211         "basename": "unsignedInt",
       
  2212         "extract": GenerateIntegerExtraction(minInclusive=0,maxExclusive=2**32),
       
  2213         "facets": DECIMAL_FACETS,
       
  2214         "generate": GenerateSimpleTypeXMLText(str),
       
  2215         "initial": lambda: 0,
       
  2216         "check": lambda x: isinstance(x, IntType)
       
  2217     },
       
  2218 
       
  2219     "short": {
       
  2220         "type": SIMPLETYPE,
       
  2221         "basename": "short",
       
  2222         "extract": GenerateIntegerExtraction(minInclusive=-2**15,maxExclusive=2**15),
       
  2223         "facets": DECIMAL_FACETS,
       
  2224         "generate": GenerateSimpleTypeXMLText(str),
       
  2225         "initial": lambda: 0,
       
  2226         "check": lambda x: isinstance(x, IntType)
       
  2227     },
       
  2228 
       
  2229     "unsignedShort": {
       
  2230         "type": SIMPLETYPE,
       
  2231         "basename": "unsignedShort", 
       
  2232         "extract": GenerateIntegerExtraction(minInclusive=0,maxExclusive=2**16),
       
  2233         "facets": DECIMAL_FACETS,
       
  2234         "generate": GenerateSimpleTypeXMLText(str),
       
  2235         "initial": lambda: 0,
       
  2236         "check": lambda x: isinstance(x, IntType)
       
  2237     },
       
  2238 
       
  2239     "byte": {
       
  2240         "type": SIMPLETYPE,
       
  2241         "basename": "byte",
       
  2242         "extract": GenerateIntegerExtraction(minInclusive=-2**7,maxExclusive=2**7),
       
  2243         "facets": DECIMAL_FACETS,
       
  2244         "generate": GenerateSimpleTypeXMLText(str),
       
  2245         "initial": lambda: 0,
       
  2246         "check": lambda x: isinstance(x, IntType)
       
  2247     },
       
  2248 
       
  2249     "unsignedByte": {
       
  2250         "type": SIMPLETYPE,
       
  2251         "basename": "unsignedByte",
       
  2252         "extract": GenerateIntegerExtraction(minInclusive=0,maxExclusive=2**8),
       
  2253         "facets": DECIMAL_FACETS,
       
  2254         "generate": GenerateSimpleTypeXMLText(str),
       
  2255         "initial": lambda: 0,
       
  2256         "check": lambda x: isinstance(x, IntType)
       
  2257     },
       
  2258 
       
  2259     "decimal": {
       
  2260         "type": SIMPLETYPE,
       
  2261         "basename": "decimal",
       
  2262         "extract": GenerateFloatExtraction("decimal"),
       
  2263         "facets": DECIMAL_FACETS,
       
  2264         "generate": GenerateFloatXMLText(),
       
  2265         "initial": lambda: 0.,
       
  2266         "check": lambda x: isinstance(x, (IntType, FloatType))
       
  2267     },
       
  2268 
       
  2269     "float": {
       
  2270         "type": SIMPLETYPE,
       
  2271         "basename": "float",
       
  2272         "extract": GenerateFloatExtraction("float", ["INF", "-INF", "NaN"]),
       
  2273         "facets": NUMBER_FACETS,
       
  2274         "generate": GenerateFloatXMLText(["INF", "-INF", "NaN"]),
       
  2275         "initial": lambda: 0.,
       
  2276         "check": lambda x: {"INF" : True, "-INF" : True, "NaN" : True}.get(x, isinstance(x, (IntType, FloatType)))
       
  2277     },
       
  2278 
       
  2279     "double": {
       
  2280         "type": SIMPLETYPE,
       
  2281         "basename": "double",
       
  2282         "extract": GenerateFloatExtraction("double", ["INF", "-INF", "NaN"]),
       
  2283         "facets": NUMBER_FACETS,
       
  2284         "generate": GenerateFloatXMLText(["INF", "-INF", "NaN"]),
       
  2285         "initial": lambda: 0.,
       
  2286         "check": lambda x: {"INF" : True, "-INF" : True, "NaN" : True}.get(x, isinstance(x, (IntType, FloatType)))
       
  2287     },
       
  2288 
       
  2289     "boolean": {
       
  2290         "type": SIMPLETYPE,
       
  2291         "basename": "boolean",
       
  2292         "extract": GetBoolean,
       
  2293         "facets": GenerateDictFacets(["pattern", "whiteSpace"]),
       
  2294         "generate": GenerateSimpleTypeXMLText(lambda x:{True : "true", False : "false"}[x]),
       
  2295         "initial": lambda: False,
       
  2296         "check": lambda x: isinstance(x, BooleanType)
       
  2297     },	
       
  2298 
       
  2299     "duration": {
       
  2300         "type": SIMPLETYPE,
       
  2301         "basename": "duration",
       
  2302         "extract": NotSupportedYet("duration"),
       
  2303         "facets": NUMBER_FACETS,
       
  2304         "generate": GenerateSimpleTypeXMLText(str),
       
  2305         "initial": lambda: "",
       
  2306         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2307     },
       
  2308 
       
  2309     "dateTime": {
       
  2310         "type": SIMPLETYPE,
       
  2311         "basename": "dateTime",
       
  2312         "extract": GetDateTime,
       
  2313         "facets": NUMBER_FACETS,
       
  2314         "generate": GenerateSimpleTypeXMLText(datetime.datetime.isoformat),
       
  2315         "initial": lambda: datetime.datetime(1,1,1,0,0,0,0),
       
  2316         "check": lambda x: isinstance(x, datetime.datetime)
       
  2317     },
       
  2318 
       
  2319     "date": {
       
  2320         "type": SIMPLETYPE,
       
  2321         "basename": "date",
       
  2322         "extract": GetDate,
       
  2323         "facets": NUMBER_FACETS,
       
  2324         "generate": GenerateSimpleTypeXMLText(datetime.date.isoformat),
       
  2325         "initial": lambda: datetime.date(1,1,1),
       
  2326         "check": lambda x: isinstance(x, datetime.date)
       
  2327     },
       
  2328     
       
  2329     "time": {
       
  2330         "type": SIMPLETYPE,
       
  2331         "basename": "time",
       
  2332         "extract": GetTime,
       
  2333         "facets": NUMBER_FACETS,
       
  2334         "generate": GenerateSimpleTypeXMLText(datetime.time.isoformat),
       
  2335         "initial": lambda: datetime.time(0,0,0,0),
       
  2336         "check": lambda x: isinstance(x, datetime.time)
       
  2337     },
       
  2338 
       
  2339     "gYear": {
       
  2340         "type": SIMPLETYPE,
       
  2341         "basename": "gYear",
       
  2342         "extract": NotSupportedYet("gYear"),
       
  2343         "facets": NUMBER_FACETS,
       
  2344         "generate": GenerateSimpleTypeXMLText(str),
       
  2345         "initial": lambda: "",
       
  2346         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2347     },
       
  2348 
       
  2349     "gYearMonth": {
       
  2350         "type": SIMPLETYPE,
       
  2351         "basename": "gYearMonth",
       
  2352         "extract": NotSupportedYet("gYearMonth"),
       
  2353         "facets": NUMBER_FACETS,
       
  2354         "generate": GenerateSimpleTypeXMLText(str),
       
  2355         "initial": lambda: "",
       
  2356         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2357     },
       
  2358 
       
  2359     "gMonth": {
       
  2360         "type": SIMPLETYPE,
       
  2361         "basename": "gMonth",
       
  2362         "extract": NotSupportedYet("gMonth"),
       
  2363         "facets": NUMBER_FACETS,
       
  2364         "generate": GenerateSimpleTypeXMLText(str),
       
  2365         "initial": lambda: "",
       
  2366         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2367     },
       
  2368 
       
  2369     "gMonthDay": {
       
  2370         "type": SIMPLETYPE,
       
  2371         "basename": "gMonthDay",
       
  2372         "extract": NotSupportedYet("gMonthDay"),
       
  2373         "facets": NUMBER_FACETS,
       
  2374         "generate": GenerateSimpleTypeXMLText(str),
       
  2375         "initial": lambda: "",
       
  2376         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2377     },
       
  2378 
       
  2379     "gDay": {
       
  2380         "type": SIMPLETYPE,
       
  2381         "basename": "gDay",
       
  2382         "extract": NotSupportedYet("gDay"),
       
  2383         "facets": NUMBER_FACETS,
       
  2384         "generate": GenerateSimpleTypeXMLText(str),
       
  2385         "initial": lambda: "",
       
  2386         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2387     },
       
  2388 
       
  2389     "Name": {
       
  2390         "type": SIMPLETYPE,
       
  2391         "basename": "Name",
       
  2392         "extract": GenerateModelNameExtraction("Name", Name_model),
       
  2393         "facets": STRING_FACETS,
       
  2394         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2395         "initial": lambda: "",
       
  2396         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2397     },
       
  2398     
       
  2399     "QName": {
       
  2400         "type": SIMPLETYPE,
       
  2401         "basename": "QName",
       
  2402         "extract": GenerateModelNameExtraction("QName", QName_model),
       
  2403         "facets": STRING_FACETS,
       
  2404         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2405         "initial": lambda: "",
       
  2406         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2407     },
       
  2408 
       
  2409     "NCName": {
       
  2410         "type": SIMPLETYPE,
       
  2411         "basename": "NCName",
       
  2412         "extract": GenerateModelNameExtraction("NCName", NCName_model),
       
  2413         "facets": STRING_FACETS,
       
  2414         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2415         "initial": lambda: "",
       
  2416         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2417     },
       
  2418 
       
  2419     "anyURI": {
       
  2420         "type": SIMPLETYPE,
       
  2421         "basename": "anyURI",
       
  2422         "extract": GenerateModelNameExtraction("anyURI", URI_model),
       
  2423         "facets": STRING_FACETS,
       
  2424         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2425         "initial": lambda: "",
       
  2426         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2427     },
       
  2428 
       
  2429     "language": {
       
  2430         "type": SIMPLETYPE,
       
  2431         "basename": "language",
       
  2432         "extract": GenerateModelNameExtraction("language", LANGUAGE_model),
       
  2433         "facets": STRING_FACETS,
       
  2434         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2435         "initial": lambda: "en",
       
  2436         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2437     },
       
  2438 
       
  2439     "ID": {
       
  2440         "type": SIMPLETYPE,
       
  2441         "basename": "ID",
       
  2442         "extract": GenerateModelNameExtraction("ID", Name_model),
       
  2443         "facets": STRING_FACETS,
       
  2444         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2445         "initial": lambda: "",
       
  2446         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2447     },
       
  2448 
       
  2449     "IDREF": {
       
  2450         "type": SIMPLETYPE,
       
  2451         "basename": "IDREF",
       
  2452         "extract": GenerateModelNameExtraction("IDREF", Name_model),
       
  2453         "facets": STRING_FACETS,
       
  2454         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2455         "initial": lambda: "",
       
  2456         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2457     },
       
  2458 
       
  2459     "IDREFS": {
       
  2460         "type": SIMPLETYPE,
       
  2461         "basename": "IDREFS",
       
  2462         "extract": GenerateModelNameExtraction("IDREFS", Names_model),
       
  2463         "facets": STRING_FACETS,
       
  2464         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2465         "initial": lambda: "",
       
  2466         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2467     },
       
  2468 
       
  2469     "ENTITY": {
       
  2470         "type": SIMPLETYPE,
       
  2471         "basename": "ENTITY",
       
  2472         "extract": GenerateModelNameExtraction("ENTITY", Name_model),
       
  2473         "facets": STRING_FACETS,
       
  2474         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2475         "initial": lambda: "",
       
  2476         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2477     },
       
  2478 
       
  2479     "ENTITIES": {
       
  2480         "type": SIMPLETYPE,
       
  2481         "basename": "ENTITIES",
       
  2482         "extract": GenerateModelNameExtraction("ENTITIES", Names_model),
       
  2483         "facets": STRING_FACETS,
       
  2484         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2485         "initial": lambda: "",
       
  2486         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2487     },
       
  2488 
       
  2489     "NOTATION": {
       
  2490         "type": SIMPLETYPE,
       
  2491         "basename": "NOTATION",
       
  2492         "extract": GenerateModelNameExtraction("NOTATION", Name_model),
       
  2493         "facets": STRING_FACETS,
       
  2494         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2495         "initial": lambda: "",
       
  2496         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2497     },
       
  2498 
       
  2499     "NMTOKEN": {
       
  2500         "type": SIMPLETYPE,
       
  2501         "basename": "NMTOKEN",
       
  2502         "extract": GenerateModelNameExtraction("NMTOKEN", NMToken_model),
       
  2503         "facets": STRING_FACETS,
       
  2504         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2505         "initial": lambda: "",
       
  2506         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2507     },
       
  2508 
       
  2509     "NMTOKENS": {
       
  2510         "type": SIMPLETYPE,
       
  2511         "basename": "NMTOKENS",
       
  2512         "extract": GenerateModelNameExtraction("NMTOKENS", NMTokens_model),
       
  2513         "facets": STRING_FACETS,
       
  2514         "generate": GenerateSimpleTypeXMLText(lambda x: x),
       
  2515         "initial": lambda: "",
       
  2516         "check": lambda x: isinstance(x, (StringType, UnicodeType))
       
  2517     },
       
  2518 
       
  2519     # Complex Types
       
  2520     "anyType": {"type": COMPLEXTYPE, "extract": lambda x:None},
       
  2521 }
       
  2522 
       
  2523 if __name__ == '__main__':
       
  2524     classes = GenerateClassesFromXSD("test.xsd")
       
  2525     
       
  2526     # Code for test of test.xsd
       
  2527     xmlfile = open("po.xml", 'r')
       
  2528     tree = minidom.parse(xmlfile)
       
  2529     xmlfile.close()
       
  2530     test = classes["PurchaseOrderType"]()
       
  2531     for child in tree.childNodes:
       
  2532         if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "purchaseOrder":
       
  2533             test.loadXMLTree(child)
       
  2534     test.items.item[0].setquantity(2)
       
  2535     testfile = open("test.xml", 'w')
       
  2536     testfile.write(u'<?xml version=\"1.0\"?>\n')
       
  2537     testfile.write(test.generateXMLText("purchaseOrder").encode("utf-8"))
       
  2538     testfile.close()