xmlclass/xsdschema.py
changeset 592 89ff2738ef20
parent 565 94c11207aa6f
child 674 bbffe4110141
equal deleted inserted replaced
591:4d6719c51f05 592:89ff2738ef20
    20 #
    20 #
    21 #You should have received a copy of the GNU General Public
    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
    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
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    25 import re
    25 import os, re
    26 import datetime
    26 import datetime
    27 from xml.dom import minidom
    27 from xml.dom import minidom
    28 from types import *
    28 from types import *
    29 
    29 
    30 from xmlclass import *
    30 from xmlclass import *
   141     if len(union["memberTypes"]) == 0:
   141     if len(union["memberTypes"]) == 0:
   142         raise ValueError("No base type has been defined for union!")
   142         raise ValueError("No base type has been defined for union!")
   143     return union
   143     return union
   144 
   144 
   145 
   145 
   146 def ReduceSimpleType(factory, attributes, elements):
   146 def CreateSimpleType(factory, attributes, typeinfos):
   147     # Reduce all the simple type children
       
   148     annotations, children = factory.ReduceElements(elements)
       
   149     
       
   150     typeinfos = children[0]
       
   151     
       
   152     # Initialize type informations
   147     # Initialize type informations
   153     facets = {}
   148     facets = {}
   154     simpleType = {"type": SIMPLETYPE, "final": attributes.get("final", []), "doc": annotations}
   149     simpleType = {"type": SIMPLETYPE, "final": attributes.get("final", [])}
   155     if attributes.has_key("name"):
   150     if attributes.has_key("name"):
   156         simpleType["name"] = attributes["name"]
   151         simpleType["name"] = attributes["name"]
   157     
   152     
   158     if typeinfos["type"] == "restriction":
   153     if typeinfos["type"] in ["restriction", "extension"]:
   159         # Search for base type definition
   154         # Search for base type definition
   160         if isinstance(typeinfos["base"], (StringType, UnicodeType)):
   155         if isinstance(typeinfos["base"], (StringType, UnicodeType)):
   161             basetypeinfos = factory.FindSchemaElement(typeinfos["base"], SIMPLETYPE)
   156             basetypeinfos = factory.FindSchemaElement(typeinfos["base"], SIMPLETYPE)
   162             if basetypeinfos is None:
   157             if basetypeinfos is None:
   163                 raise "\"%s\" isn't defined!" % typeinfos["base"] 
   158                 raise "\"%s\" isn't defined!" % typeinfos["base"] 
   170         
   165         
   171         simpleType["basename"] = basetypeinfos["basename"]
   166         simpleType["basename"] = basetypeinfos["basename"]
   172         
   167         
   173         # Check that derivation is allowed
   168         # Check that derivation is allowed
   174         if basetypeinfos.has_key("final"):
   169         if basetypeinfos.has_key("final"):
   175             if basetypeinfos["final"].has_key("#all"):
   170             if "#all" in basetypeinfos["final"]:
   176                 raise ValueError("Base type can't be derivated!")
   171                 raise ValueError("Base type can't be derivated!")
   177             if basetypeinfos["final"].has_key("restriction"):
   172             if "restriction" in basetypeinfos["final"] and typeinfos["type"] == "restriction":
   178                 raise ValueError("Base type can't be derivated by restriction!")
   173                 raise ValueError("Base type can't be derivated by restriction!")
   179         
   174         
   180         # Extract simple type facets
   175         # Extract simple type facets
   181         for facet in typeinfos["facets"]:
   176         for facet in typeinfos.get("facets", []):
   182             facettype = facet["type"]
   177             facettype = facet["type"]
   183             if not basetypeinfos["facets"].has_key(facettype):
   178             if not basetypeinfos["facets"].has_key(facettype):
   184                 raise ValueError("\"%s\" facet can't be defined for \"%s\" type!" % (facettype, type))
   179                 raise ValueError("\"%s\" facet can't be defined for \"%s\" type!" % (facettype, type))
   185             elif basetypeinfos["facets"][facettype][1]:
   180             elif basetypeinfos["facets"][facettype][1]:
   186                 raise ValueError("\"%s\" facet is fixed on base type!" % facettype)
   181                 raise ValueError("\"%s\" facet is fixed on base type!" % facettype)
   187             value = facet["value"]
   182             value = facet["value"]
   188             basevalue = basetypeinfos["facets"][facettype][0]
   183             basevalue = basetypeinfos["facets"][facettype][0]
   189             if facettype == "enumeration":
   184             if facettype in ["enumeration", "pattern"]:
   190                 value = basetypeinfos["extract"](value, False)
   185                 value = basetypeinfos["extract"](value, False)
   191                 if len(facets) == 0:
   186                 if len(facets) == 0:
   192                     facets["enumeration"] = ([value], False)
   187                     facets[facettype] = ([value], False)
   193                     continue
   188                     continue
   194                 elif facets.keys() == ["enumeration"]:
   189                 elif facets.keys() == [facettype]:
   195                     facets["enumeration"][0].append(value)
   190                     facets[facettype][0].append(value)
   196                     continue
   191                     continue
   197                 else:
   192                 else:
   198                     raise ValueError("\"enumeration\" facet can't be defined with another facet type!")
   193                     raise ValueError("\"%s\" facet can't be defined with another facet type!" % facettype)
   199             elif facets.has_key("enumeration"):
   194             elif facets.has_key("enumeration"):
   200                 raise ValueError("\"enumeration\" facet can't be defined with another facet type!")
   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!")
   201             elif facets.has_key(facettype):
   198             elif facets.has_key(facettype):
   202                 raise ValueError("\"%s\" facet can't be defined two times!" % facettype)
   199                 raise ValueError("\"%s\" facet can't be defined two times!" % facettype)
   203             elif facettype == "length":
   200             elif facettype == "length":
   204                 if facets.has_key("minLength"):
   201                 if facets.has_key("minLength"):
   205                     raise ValueError("\"length\" and \"minLength\" facets can't be defined at the same time!")
   202                     raise ValueError("\"length\" and \"minLength\" facets can't be defined at the same time!")
   311                     elif facetname == "maxInclusive" and value > facetvalue:
   308                     elif facetname == "maxInclusive" and value > facetvalue:
   312                         raise ValueError("value must be lesser than or equal to %s" % str(facetvalue))
   309                         raise ValueError("value must be lesser than or equal to %s" % str(facetvalue))
   313                     elif facetname == "maxExclusive"  and value >= facetvalue:
   310                     elif facetname == "maxExclusive"  and value >= facetvalue:
   314                         raise ValueError("value must be lesser than %s" % str(facetvalue))
   311                         raise ValueError("value must be lesser than %s" % str(facetvalue))
   315                     elif facetname == "pattern":
   312                     elif facetname == "pattern":
   316                         model = re.compile("(?:%s)?$" % facetvalue)
   313                         model = re.compile("(?:%s)?$" % "|".join(map(lambda x: "(?:%s)" % x, facetvalue)))
   317                         result = model.match(value)
   314                         result = model.match(value)
   318                         if result is None:
   315                         if result is None:
   319                             raise ValueError("value doesn't follow the pattern %s" % facetvalue)
   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":
   320                     elif facetname == "whiteSpace":
   321                         if facetvalue == "replace":
   321                         if facetvalue == "replace":
   322                             value = GetNormalizedString(value, False)
   322                             value = GetNormalizedString(value, False)
   323                         elif facetvalue == "collapse":
   323                         elif facetvalue == "collapse":
   324                             value = GetToken(value, False)
   324                             value = GetToken(value, False)
   342                     elif facetname == "maxInclusive" and value > facetvalue:
   342                     elif facetname == "maxInclusive" and value > facetvalue:
   343                         return False
   343                         return False
   344                     elif facetname == "maxExclusive"  and value >= facetvalue:
   344                     elif facetname == "maxExclusive"  and value >= facetvalue:
   345                         return False
   345                         return False
   346                     elif facetname == "pattern":
   346                     elif facetname == "pattern":
   347                         model = re.compile("(?:%s)?$" % facetvalue)
   347                         model = re.compile("(?:%s)?$" % "|".join(map(lambda x: "(?:%s)" % x, facetvalue)))
   348                         result = model.match(value)
   348                         result = model.match(value)
   349                         if result is None:
   349                         if result is None:
   350                             raise ValueError("value doesn't follow the pattern %s" % facetvalue)
   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])
   351             return True
   354             return True
   352         
   355         
   353         def SimpleTypeInitialValue():
   356         def SimpleTypeInitialValue():
   354             for facetname, (facetvalue, facetfixed) in facets.items():
   357             for facetname, (facetvalue, facetfixed) in facets.items():
   355                 if facetvalue is not None:
   358                 if facetvalue is not None:
   476     simpleType["initial"] = SimpleTypeInitialValue
   479     simpleType["initial"] = SimpleTypeInitialValue
   477     simpleType["check"] = CheckSimpleTypeValue
   480     simpleType["check"] = CheckSimpleTypeValue
   478     simpleType["generate"] = GenerateSimpleType
   481     simpleType["generate"] = GenerateSimpleType
   479     return simpleType
   482     return simpleType
   480 
   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
   481 
   492 
   482 # Complex type
   493 # Complex type
   483 
   494 
   484 def ExtractAttributes(factory, elements, base = None):
   495 def ExtractAttributes(factory, elements, base=None):
       
   496     attrs = []
       
   497     attrnames = {}
   485     if base is not None:
   498     if base is not None:
   486         basetypeinfos = factory.FindSchemaElement(base, COMPLEXTYPE)
   499         basetypeinfos = factory.FindSchemaElement(base)
   487         if isinstance(basetypeinfos, (UnicodeType, StringType)):
   500         if not isinstance(basetypeinfos, (UnicodeType, StringType)) and basetypeinfos["type"] == COMPLEXTYPE:
   488             attrnames = {}
       
   489         else:
       
   490             attrnames = dict(map(lambda x:(x["name"], True), basetypeinfos["attributes"]))
   501             attrnames = dict(map(lambda x:(x["name"], True), basetypeinfos["attributes"]))
   491     else:
   502         
   492         attrnames = {}
       
   493     attrs = []
       
   494     for element in elements:
   503     for element in elements:
   495         if element["type"] == ATTRIBUTE:
   504         if element["type"] == ATTRIBUTE:
   496             if attrnames.get(element["name"], False):
   505             if attrnames.get(element["name"], False):
   497                 raise ValueError("\"%s\" attribute has been defined two times!" % element["name"])
   506                 raise ValueError("\"%s\" attribute has been defined two times!" % element["name"])
   498             else:
   507             else:
   522     if restriction["base"] is None:
   531     if restriction["base"] is None:
   523         raise ValueError("No base type has been defined for restriction!")
   532         raise ValueError("No base type has been defined for restriction!")
   524     
   533     
   525     while len(children) > 0 and children[0]["type"] in ALL_FACETS:
   534     while len(children) > 0 and children[0]["type"] in ALL_FACETS:
   526         restriction["facets"].append(children.pop(0))
   535         restriction["facets"].append(children.pop(0))
   527     restriction["attributes"] = ExtractAttributes(factory, children)
   536     restriction["attributes"] = ExtractAttributes(factory, children, restriction["base"])
   528     return restriction
   537     return restriction
   529 
   538 
   530 
   539 
   531 def ReduceExtension(factory, attributes, elements):
   540 def ReduceExtension(factory, attributes, elements):
   532     annotations, children = factory.ReduceElements(elements)
   541     annotations, children = factory.ReduceElements(elements)
   533     extension = {"type": "extension", "attributes": [], "elements": [], "base": attributes.get("base", None), "doc": annotations}
   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}
   534     if len(children) > 0:
   545     if len(children) > 0:
   535         if children[0]["type"] in ["group", "all", CHOICE, "sequence"]:
   546         if children[0]["type"] in ["group", "all", CHOICE, "sequence"]:
   536             group = children.pop(0)
   547             group = children.pop(0)
   537             if group["type"] in ["all", "sequence"]:
   548             if group["type"] in ["all", "sequence"]:
   538                 extension["elements"] = group["elements"]
   549                 extension["elements"] = group["elements"]
   548                     extension["order"] = elmtgroup["order"]
   559                     extension["order"] = elmtgroup["order"]
   549                 else:
   560                 else:
   550                     content = elmtgroup.copy()
   561                     content = elmtgroup.copy()
   551                     content["name"] = "content"
   562                     content["name"] = "content"
   552                     extension["elements"].append(content)
   563                     extension["elements"].append(content)
   553         extension["attributes"] = ExtractAttributes(factory, children, extension["base"])
   564         extension["attributes"] = ExtractAttributes(factory, children)
   554     return extension
   565     return extension
   555 
   566 
   556 
   567 
   557 def ReduceSimpleContent(factory, attributes, elements):
   568 def ReduceSimpleContent(factory, attributes, elements):
   558     annotations, children = factory.ReduceElements(elements)
   569     annotations, children = factory.ReduceElements(elements)
       
   570     
   559     simpleContent = children[0].copy()
   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}]
   560     simpleContent["type"] = "simpleContent"
   591     simpleContent["type"] = "simpleContent"
   561     return simpleContent
   592     return simpleContent
   562 
   593 
   563 
   594 
   564 def ReduceComplexContent(factory, attributes, elements):
   595 def ReduceComplexContent(factory, attributes, elements):
   568     return complexContent
   599     return complexContent
   569 
   600 
   570 
   601 
   571 def ReduceComplexType(factory, attributes, elements):
   602 def ReduceComplexType(factory, attributes, elements):
   572     annotations, children = factory.ReduceElements(elements)
   603     annotations, children = factory.ReduceElements(elements)
   573         
   604     
   574     if len(children) > 0:
   605     if len(children) > 0:
   575         if children[0]["type"] in ["simpleContent", "complexContent"]:
   606         if children[0]["type"] in ["simpleContent", "complexContent"]:
   576             complexType = children[0].copy()
   607             complexType = children[0].copy()
   577             complexType.update(attributes)
   608             complexType.update(attributes)
   578             complexType["type"] = COMPLEXTYPE
   609             complexType["type"] = COMPLEXTYPE
   580         elif children[0]["type"] in ["group", "all", CHOICE, "sequence"]:
   611         elif children[0]["type"] in ["group", "all", CHOICE, "sequence"]:
   581             complexType = {"type": COMPLEXTYPE, "elements": [], "order": True, "doc": annotations}
   612             complexType = {"type": COMPLEXTYPE, "elements": [], "order": True, "doc": annotations}
   582             complexType.update(attributes)
   613             complexType.update(attributes)
   583             group = children.pop(0)
   614             group = children.pop(0)
   584             if group["type"] in ["all", "sequence"]:
   615             if group["type"] in ["all", "sequence"]:
   585                 if group["minOccurs"] == 0 or group["maxOccurs"] != 1:
   616                 choice_number = 0
   586                     if len(group["elements"]) > 1:
   617                 for element in group["elements"]:
   587                         raise ValueError("Not supported yet!")
   618                     if element["type"] == CHOICE:
   588                     if group["minOccurs"] == 0:
   619                         choice_number += 1
   589                         group["elements"][0]["minOccurs"] = group["minOccurs"]
   620                 if (group["minOccurs"] == 0 or group["maxOccurs"] != 1) and len(group["elements"]) > 1 or choice_number > 1:
   590                     if group["maxOccurs"] != 1:
   621                     content = {"type": CHOICE, "name": "content", "choices": [group], "minOccurs": 1, "maxOccurs": 1}
   591                         group["elements"][0]["maxOccurs"] = group["maxOccurs"]
   622                     complexType["elements"].append(content)
   592                 complexType["elements"] = group["elements"]
   623                 else:
   593                 complexType["order"] = group["order"]
   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"]
   594             elif group["type"] == CHOICE:
   634             elif group["type"] == CHOICE:
   595                 content = group.copy()
   635                 content = group.copy()
   596                 content["name"] = "content"
   636                 content["name"] = "content"
   597                 complexType["elements"].append(content)
   637                 complexType["elements"].append(content)
   598             elif group["type"] == "group":
   638             elif group["type"] == "group":
   671     any = {"type": ANY, "doc": annotations}
   711     any = {"type": ANY, "doc": annotations}
   672     any.update(attributes)
   712     any.update(attributes)
   673     return any
   713     return any
   674 
   714 
   675 def ReduceElement(factory, attributes, elements):
   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     
   676     if attributes.has_key("default") and attributes.has_key("fixed"):
   726     if attributes.has_key("default") and attributes.has_key("fixed"):
   677         raise ValueError("\"default\" and \"fixed\" can't be defined at the same time!")
   727         raise ValueError("\"default\" and \"fixed\" can't be defined at the same time!")
   678     
   728     
   679     if attributes.has_key("ref"):
   729     if attributes.has_key("ref"):
   680         annotations, children = factory.ReduceElements(elements)
       
   681         
       
   682         for attr in ["name", "default", "fixed", "form", "block", "type"]:
   730         for attr in ["name", "default", "fixed", "form", "block", "type"]:
   683             if attributes.has_key(attr):
   731             if attributes.has_key(attr):
   684                 raise ValueError("\"ref\" and \"%s\" can't be defined at the same time!" % attr)
   732                 raise ValueError("\"ref\" and \"%s\" can't be defined at the same time!" % attr)
   685         if attributes.has_key("nillable"):
   733         if attributes.has_key("nillable"):
   686             raise ValueError("\"ref\" and \"nillable\" can't be defined at the same time!")
   734             raise ValueError("\"ref\" and \"nillable\" can't be defined at the same time!")
   687         if len(children) > 0:
   735         if len(types) > 0:
   688             raise ValueError("No type and no constraints can be defined where \"ref\" is defined!")
   736             raise ValueError("No type and no constraints can be defined where \"ref\" is defined!")
   689     
   737     
   690         infos = factory.FindSchemaElement(attributes["ref"], ELEMENT)
   738         infos = factory.FindSchemaElement(attributes["ref"], ELEMENT)
   691         if infos is not None:
   739         if infos is not None:
   692             element = infos.copy()
   740             element = infos.copy()
       
   741             element["constraints"] = constraints
   693             element["minOccurs"] = attributes["minOccurs"]
   742             element["minOccurs"] = attributes["minOccurs"]
   694             element["maxOccurs"] = attributes["maxOccurs"]
   743             element["maxOccurs"] = attributes["maxOccurs"]
   695             return element
   744             return element
   696         else:
   745         else:
   697             raise ValueError("\"%s\" base type isn't defined or circular referenced!" % name)
   746             raise ValueError("\"%s\" base type isn't defined or circular referenced!" % name)
   698     
   747     
   699     elif attributes.has_key("name"):
   748     elif attributes.has_key("name"):
   700         annotations, children = factory.ReduceElements(elements)
   749         element = {"type": ELEMENT, "elmt_type": attributes.get("type", None), "constraints": constraints, "doc": annotations}
   701         
   750         if len(types) > 0:
   702         element = {"type": ELEMENT, "elmt_type": attributes.get("type", None), "doc": annotations}
       
   703         if len(children) > 0:
       
   704             if element["elmt_type"] is None:
   751             if element["elmt_type"] is None:
   705                 element["elmt_type"] = children[0]
   752                 element["elmt_type"] = types[0]
   706             else:
   753             else:
   707                 raise ValueError("Only one type can be defined for attribute!")
   754                 raise ValueError("Only one type can be defined for attribute!")
   708         elif element["elmt_type"] is None:
   755         elif element["elmt_type"] is None:
   709             element["elmt_type"] = "tag"
   756             element["elmt_type"] = "tag"
   710             element["type"] = TAG
   757             element["type"] = TAG
   736     choices = []
   783     choices = []
   737     for child in children:
   784     for child in children:
   738         if child["type"] in [ELEMENT, ANY, TAG]:
   785         if child["type"] in [ELEMENT, ANY, TAG]:
   739             choices.append(child)
   786             choices.append(child)
   740         elif child["type"] == "sequence":
   787         elif child["type"] == "sequence":
   741             raise ValueError("\"sequence\" in \"choice\" is not supported. Create instead a new complex type!")
   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!")
   742         elif child["type"] == CHOICE:
   791         elif child["type"] == CHOICE:
   743             choices.extend(child["choices"])
   792             choices.extend(child["choices"])
   744         elif child["type"] == "group":
   793         elif child["type"] == "group":
   745             elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP) 
   794             elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP) 
   746             if not elmtgroup.has_key("choices"):
   795             if not elmtgroup.has_key("choices"):
   765 def ReduceSequence(factory, attributes, elements):
   814 def ReduceSequence(factory, attributes, elements):
   766     annotations, children = factory.ReduceElements(elements)
   815     annotations, children = factory.ReduceElements(elements)
   767     
   816     
   768     sequence = []
   817     sequence = []
   769     for child in children:
   818     for child in children:
   770         if child["type"] in [ELEMENT, ANY, TAG]:
   819         if child["type"] in [ELEMENT, ANY, TAG, CHOICE]:
   771             sequence.append(child)
   820             sequence.append(child)
   772         elif child["type"] == CHOICE:
       
   773             content = child.copy()
       
   774             content["name"] = "content"
       
   775             sequence.append(content)
       
   776         elif child["type"] == "sequence":
   821         elif child["type"] == "sequence":
   777             sequence.extend(child["elements"])
   822             sequence.extend(child["elements"])
   778         elif child["type"] == "group":
   823         elif child["type"] == "group":
   779             elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP)
   824             elmtgroup = factory.FindSchemaElement(child["ref"], ELEMENTSGROUP)
   780             if not elmtgroup.has_key("elements") or not elmtgroup["order"]:
   825             if not elmtgroup.has_key("elements") or not elmtgroup["order"]:
   813 
   858 
   814 # Constraint elements
   859 # Constraint elements
   815 
   860 
   816 def ReduceUnique(factory, attributes, elements):
   861 def ReduceUnique(factory, attributes, elements):
   817     annotations, children = factory.ReduceElements(elements)
   862     annotations, children = factory.ReduceElements(elements)
   818     raise ValueError("\"unique\" element isn't supported yet!")
   863     
   819 
   864     unique = {"type": CONSTRAINT, "const_type": "unique", "selector": children[0], "fields": children[1:]}
       
   865     unique.update(attributes)
       
   866     return unique
       
   867     
   820 def ReduceKey(factory, attributes, elements):
   868 def ReduceKey(factory, attributes, elements):
   821     annotations, children = factory.ReduceElements(elements)
   869     annotations, children = factory.ReduceElements(elements)
   822     raise ValueError("\"key\" element isn't supported yet!")
   870     
   823     
   871     key = {"type": CONSTRAINT, "const_type": "key", "selector": children[0], "fields": children[1:]}
       
   872     key.update(attributes)
       
   873     return key
       
   874 
   824 def ReduceKeyRef(factory, attributes, elements):
   875 def ReduceKeyRef(factory, attributes, elements):
   825     annotations, children = factory.ReduceElements(elements)
   876     annotations, children = factory.ReduceElements(elements)
   826     raise ValueError("\"keyref\" element isn't supported yet!")
   877     
       
   878     keyref = {"type": CONSTRAINT, "const_type": "keyref", "selector": children[0], "fields": children[1:]}
       
   879     keyref.update(attributes)
       
   880     return keyref
   827     
   881     
   828 def ReduceSelector(factory, attributes, elements):
   882 def ReduceSelector(factory, attributes, elements):
   829     annotations, children = factory.ReduceElements(elements)
   883     annotations, children = factory.ReduceElements(elements)
   830     raise ValueError("\"selector\" element isn't supported yet!")
   884     
       
   885     selector = {"type": CONSTRAINT, "const_type": "selector"}
       
   886     selector.update(attributes)
       
   887     return selector
   831 
   888 
   832 def ReduceField(factory, attributes, elements):
   889 def ReduceField(factory, attributes, elements):
   833     annotations, children = factory.ReduceElements(elements)
   890     annotations, children = factory.ReduceElements(elements)
   834     raise ValueError("\"field\" element isn't supported yet!")
   891     
       
   892     field = {"type": CONSTRAINT, "const_type": "field"}
       
   893     field.update(attributes)
       
   894     return field
   835     
   895     
   836 
   896 
   837 # Inclusion elements
   897 # Inclusion elements
   838 
   898 
   839 def ReduceImport(factory, attributes, elements):
   899 def ReduceImport(factory, attributes, elements):
   840     annotations, children = factory.ReduceElements(elements)
   900     annotations, children = factory.ReduceElements(elements)
   841     raise ValueError("\"import\" element isn't supported yet!")
   901     raise ValueError("\"import\" element isn't supported yet!")
   842 
   902 
   843 def ReduceInclude(factory, attributes, elements):
   903 def ReduceInclude(factory, attributes, elements):
   844     annotations, children = factory.ReduceElements(elements)
   904     annotations, children = factory.ReduceElements(elements)
   845     raise ValueError("\"include\" element isn't supported yet!")
   905     
       
   906     if factory.FileName is None:
       
   907         raise ValueError("Include in XSD string not yet supported")
       
   908     filepath = attributes["schemaLocation"]
       
   909     if filepath is not None and not os.path.exists(filepath):
       
   910         filepath = os.path.join(factory.BaseFolder, filepath)
       
   911         if not os.path.exists(filepath):
       
   912             raise ValueError("No file '%s' found for include" % attributes["schemaLocation"])
       
   913     xsdfile = open(filepath, 'r')
       
   914     include_factory = XSDClassFactory(minidom.parse(xsdfile), filepath)
       
   915     xsdfile.close()
       
   916     include_factory.CreateClasses()
       
   917     
       
   918     if factory.TargetNamespace == include_factory.TargetNamespace:
       
   919         factory.Namespaces[factory.TargetNamespace].update(include_factory.Namespaces[include_factory.TargetNamespace])
       
   920     else:
       
   921         factory.Namespaces[include_factory.TargetNamespace] = include_factory.Namespaces[include_factory.TargetNamespace]
       
   922     factory.ComputedClasses.update(include_factory.ComputedClasses)
       
   923     return None
   846     
   924     
   847 def ReduceRedefine(factory, attributes, elements):
   925 def ReduceRedefine(factory, attributes, elements):
   848     annotations, children = factory.ReduceElements(elements)
   926     annotations, children = factory.ReduceElements(elements)
   849     raise ValueError("\"redefine\" element isn't supported yet!")
   927     raise ValueError("\"redefine\" element isn't supported yet!")
   850 
   928 
   883     elif isinstance(schema, DictType):
   961     elif isinstance(schema, DictType):
   884         if not isinstance(reference, DictType) or len(schema) != len(reference):
   962         if not isinstance(reference, DictType) or len(schema) != len(reference):
   885             return False
   963             return False
   886         for name, value in schema.items():
   964         for name, value in schema.items():
   887             ref_value = reference.get(name, None)
   965             ref_value = reference.get(name, None)
   888             if ref_value is None:
   966             if ref_value is None and value != None:
   889                 return False
   967                 return False
   890             result = CompareSchema(value, ref_value)
   968             result = CompareSchema(value, ref_value)
   891             if not result:
   969             if not result:
   892                 return result
   970                 return result
   893         return True
   971         return True
   903 #-------------------------------------------------------------------------------
   981 #-------------------------------------------------------------------------------
   904 
   982 
   905 
   983 
   906 class XSDClassFactory(ClassFactory):
   984 class XSDClassFactory(ClassFactory):
   907 
   985 
   908     def __init__(self, document, debug = False):
   986     def __init__(self, document, filepath=None, debug=False):
   909         ClassFactory.__init__(self, document, debug)
   987         ClassFactory.__init__(self, document, filepath, debug)
   910         self.Namespaces["xml"] = {
   988         self.Namespaces["xml"] = {
   911             "lang": {
   989             "lang": {
   912                 "type": SYNTAXATTRIBUTE, 
   990                 "type": SYNTAXATTRIBUTE, 
   913                 "extract": {
   991                 "extract": {
   914                     "default": GenerateModelNameExtraction("lang", LANGUAGE_model)
   992                     "default": GenerateModelNameExtraction("lang", LANGUAGE_model)
   941                 }
  1019                 }
   942             }
  1020             }
   943         }
  1021         }
   944         
  1022         
   945     def ParseSchema(self):
  1023     def ParseSchema(self):
   946         schema = self.Document.childNodes[0]
  1024         for child in self.Document.childNodes:
       
  1025             if child.nodeType == self.Document.ELEMENT_NODE:
       
  1026                 schema = child
       
  1027                 break
   947         for qualified_name, attr in schema._attrs.items():
  1028         for qualified_name, attr in schema._attrs.items():
   948             value = GetAttributeValue(attr)
  1029             value = GetAttributeValue(attr)
   949             if value == "http://www.w3.org/2001/XMLSchema":
  1030             if value == "http://www.w3.org/2001/XMLSchema":
   950                 namespace, name = DecomposeQualifiedName(qualified_name)
  1031                 namespace, name = DecomposeQualifiedName(qualified_name)
   951                 if namespace == "xmlns":
  1032                 if namespace == "xmlns":
   955                     self.DefinedNamespaces["http://www.w3.org/2001/XMLSchema"] = self.SchemaNamespace
  1036                     self.DefinedNamespaces["http://www.w3.org/2001/XMLSchema"] = self.SchemaNamespace
   956                 self.Namespaces[self.SchemaNamespace] = XSD_NAMESPACE
  1037                 self.Namespaces[self.SchemaNamespace] = XSD_NAMESPACE
   957         self.Schema = XSD_NAMESPACE["schema"]["extract"]["default"](self, schema)
  1038         self.Schema = XSD_NAMESPACE["schema"]["extract"]["default"](self, schema)
   958         ReduceSchema(self, self.Schema[1], self.Schema[2])
  1039         ReduceSchema(self, self.Schema[1], self.Schema[2])
   959 
  1040 
   960     def FindSchemaElement(self, element_name, element_type):
  1041     def FindSchemaElement(self, element_name, element_type=None):
   961         namespace, name = DecomposeQualifiedName(element_name)
  1042         namespace, name = DecomposeQualifiedName(element_name)
   962         element = self.GetQualifiedNameInfos(name, namespace, True)
  1043         element = self.GetQualifiedNameInfos(name, namespace, True)
   963         if element is None and namespace == self.TargetNamespace and name not in self.CurrentCompilations:
  1044         if element is None and namespace == self.TargetNamespace and name not in self.CurrentCompilations:
   964             self.CurrentCompilations.append(name)
  1045             self.CurrentCompilations.append(name)
   965             element = self.CreateSchemaElement(name, element_type)
  1046             element = self.CreateSchemaElement(name, element_type)
   968                 self.Namespaces[self.TargetNamespace][name] = element
  1049                 self.Namespaces[self.TargetNamespace][name] = element
   969         if element is None:
  1050         if element is None:
   970             if name in self.CurrentCompilations:
  1051             if name in self.CurrentCompilations:
   971                 if self.Debug:
  1052                 if self.Debug:
   972                     print "Warning : \"%s\" is circular referenced!" % element_name
  1053                     print "Warning : \"%s\" is circular referenced!" % element_name
   973                 return element_name
       
   974             else:
  1054             else:
   975                 raise ValueError("\"%s\" isn't defined!" % element_name)
  1055                 raise ValueError("\"%s\" isn't defined!" % element_name)
   976         if element["type"] != element_type:
  1056         if element_type is not None and element["type"] != element_type:
   977             raise ValueError("\"%s\" isn't a group!" % element_name)
  1057             raise ValueError("\"%s\" isn't of the expected type!" % element_name)
   978         return element
  1058         return element
   979     
  1059     
   980     def CreateSchemaElement(self, element_name, element_type):
  1060     def CreateSchemaElement(self, element_name, element_type):
   981         for type, attributes, elements in self.Schema[2]:
  1061         for type, attributes, elements in self.Schema[2]:
   982             namespace, name = DecomposeQualifiedName(type)
  1062             namespace, name = DecomposeQualifiedName(type)
   983             if attributes.has_key("name") and attributes["name"] == element_name:
  1063             if attributes.get("name", None) == element_name:
   984                 element_infos = None
  1064                 element_infos = None
   985                 if element_type == ATTRIBUTE and name == "attribute":
  1065                 if element_type in (ATTRIBUTE, None) and name == "attribute":
   986                     element_infos = ReduceAttribute(self, attributes, elements)
  1066                     element_infos = ReduceAttribute(self, attributes, elements)
   987                 elif element_type == ELEMENT and name == "element":
  1067                 elif element_type in (ELEMENT, None) and name == "element":
   988                     element_infos = ReduceElement(self, attributes, elements)
  1068                     element_infos = ReduceElement(self, attributes, elements)
   989                 elif element_type == ATTRIBUTESGROUP and name == "attributeGroup":
  1069                 elif element_type in (ATTRIBUTESGROUP, None) and name == "attributeGroup":
   990                     element_infos = ReduceAttributeGroup(self, attributes, elements)
  1070                     element_infos = ReduceAttributeGroup(self, attributes, elements)
   991                 elif element_type == ELEMENTSGROUP and name == "group":
  1071                 elif element_type in (ELEMENTSGROUP, None) and name == "group":
   992                     element_infos = ReduceGroup(self, attributes, elements)
  1072                     element_infos = ReduceGroup(self, attributes, elements)
   993                 elif element_type == SIMPLETYPE and name == "simpleType":
  1073                 elif element_type in (SIMPLETYPE, None) and name == "simpleType":
   994                     element_infos = ReduceSimpleType(self, attributes, elements)
  1074                     element_infos = ReduceSimpleType(self, attributes, elements)
   995                 elif element_type == COMPLEXTYPE and name == "complexType":
  1075                 elif element_type in (COMPLEXTYPE, None) and name == "complexType":
   996                     element_infos = ReduceComplexType(self, attributes, elements)
  1076                     element_infos = ReduceComplexType(self, attributes, elements)
   997                 if element_infos is not None:
  1077                 if element_infos is not None:
   998                     self.Namespaces[self.TargetNamespace][element_name] = element_infos
  1078                     self.Namespaces[self.TargetNamespace][element_name] = element_infos
   999                     return element_infos
  1079                     return element_infos
  1000         return None
  1080         return None
  1001 
  1081 
  1002 """
  1082 """
  1003 This function opens the xsd file and generate the classes from the xml tree
  1083 This function opens the xsd file and generate the classes from the xml tree
  1004 """
  1084 """
  1005 def GenerateClassesFromXSD(filename, declare = False):
  1085 def GenerateClassesFromXSD(filepath, declare=False):
  1006     xsdfile = open(filename, 'r')
  1086     xsdfile = open(filepath, 'r')
  1007     factory = XSDClassFactory(minidom.parse(xsdfile))
  1087     factory = XSDClassFactory(minidom.parse(xsdfile), filepath)
  1008     xsdfile.close()
  1088     xsdfile.close()
  1009     factory.ParseSchema()
       
  1010     return GenerateClasses(factory, declare)
  1089     return GenerateClasses(factory, declare)
  1011 
  1090 
  1012 """
  1091 """
  1013 This function generate the classes from the xsd given as a string
  1092 This function generate the classes from the xsd given as a string
  1014 """
  1093 """
  1015 def GenerateClassesFromXSDstring(xsdstring, declare = False):
  1094 def GenerateClassesFromXSDstring(xsdstring, declare=False):
  1016     factory = XSDClassFactory(minidom.parseString(xsdstring))
  1095     return GenerateClasses(XSDClassFactory(minidom.parseString(xsdstring)), declare)
  1017     factory.ParseSchema()
       
  1018     return GenerateClasses(factory, declare)
       
  1019 
  1096 
  1020 
  1097 
  1021 #-------------------------------------------------------------------------------
  1098 #-------------------------------------------------------------------------------
  1022 #                           XSD schema syntax elements
  1099 #                           XSD schema syntax elements
  1023 #-------------------------------------------------------------------------------
  1100 #-------------------------------------------------------------------------------
  1369           Content: (annotation?, (selector, field+))
  1446           Content: (annotation?, (selector, field+))
  1370         </key>""",
  1447         </key>""",
  1371         "type": SYNTAXELEMENT, 
  1448         "type": SYNTAXELEMENT, 
  1372         "extract": {
  1449         "extract": {
  1373             "default": GenerateElement("key", ["id", "name"], 
  1450             "default": GenerateElement("key", ["id", "name"], 
  1374                 re.compile("((?:annotation )?(?:selector |(?:field )+))"))
  1451                 re.compile("((?:annotation )?(?:selector (?:field )+))"))
  1375         },
  1452         },
  1376         "reduce": ReduceKey
  1453         "reduce": ReduceKey
  1377     },
  1454     },
  1378 
  1455 
  1379     "keyref": {"struct": """
  1456     "keyref": {"struct": """
  1385           Content: (annotation?, (selector, field+))
  1462           Content: (annotation?, (selector, field+))
  1386         </keyref>""",
  1463         </keyref>""",
  1387         "type": SYNTAXELEMENT, 
  1464         "type": SYNTAXELEMENT, 
  1388         "extract": {
  1465         "extract": {
  1389             "default": GenerateElement("keyref", ["id", "name", "refer"], 
  1466             "default": GenerateElement("keyref", ["id", "name", "refer"], 
  1390                 re.compile("((?:annotation )?(?:selector |(?:field )+))"))
  1467                 re.compile("((?:annotation )?(?:selector (?:field )+))"))
  1391         },
  1468         },
  1392         "reduce": ReduceKeyRef
  1469         "reduce": ReduceKeyRef
  1393     },
  1470     },
  1394 
  1471 
  1395     "length": {"struct" : """
  1472     "length": {"struct" : """
  1984     },
  2061     },
  1985 
  2062 
  1986     "xpath": {
  2063     "xpath": {
  1987         "type": SYNTAXATTRIBUTE, 
  2064         "type": SYNTAXATTRIBUTE, 
  1988         "extract": {
  2065         "extract": {
  1989             "default": NotSupportedYet("xpath")
  2066 #            "default": NotSupportedYet("xpath")
       
  2067             "default": GetAttributeValue
  1990         }
  2068         }
  1991     },
  2069     },
  1992     
  2070     
  1993 #-------------------------------------------------------------------------------
  2071 #-------------------------------------------------------------------------------
  1994 #                           Simple types definition
  2072 #                           Simple types definition
  2029         "basename": "base64Binary", 
  2107         "basename": "base64Binary", 
  2030         "extract": NotSupportedYet("base64Binary"),
  2108         "extract": NotSupportedYet("base64Binary"),
  2031         "facets": STRING_FACETS,
  2109         "facets": STRING_FACETS,
  2032         "generate": GenerateSimpleTypeXMLText(str),
  2110         "generate": GenerateSimpleTypeXMLText(str),
  2033         "initial": lambda: 0,
  2111         "initial": lambda: 0,
  2034         "check": lambda x: isinstance(x, IntType)
  2112         "check": lambda x: isinstance(x, (IntType, LongType))
  2035     },
  2113     },
  2036     
  2114     
  2037     "hexBinary": {
  2115     "hexBinary": {
  2038         "type": SIMPLETYPE,
  2116         "type": SIMPLETYPE,
  2039         "basename": "hexBinary", 
  2117         "basename": "hexBinary", 
  2040         "extract": GetHexInteger,
  2118         "extract": GetHexInteger,
  2041         "facets": STRING_FACETS,
  2119         "facets": STRING_FACETS,
  2042         "generate": GenerateSimpleTypeXMLText(lambda x: ("%."+str(int(round(len("%X"%x)/2.)*2))+"X")%x),
  2120         "generate": GenerateSimpleTypeXMLText(lambda x: ("%."+str(int(round(len("%X"%x)/2.)*2))+"X")%x),
  2043         "initial": lambda: 0,
  2121         "initial": lambda: 0,
  2044         "check": lambda x: isinstance(x, IntType)
  2122         "check": lambda x: isinstance(x, (IntType, LongType))
  2045     },
  2123     },
  2046 
  2124 
  2047     "integer": {
  2125     "integer": {
  2048         "type": SIMPLETYPE,
  2126         "type": SIMPLETYPE,
  2049         "basename": "integer", 
  2127         "basename": "integer",