xmlclass/xsdschema.py
branchpython3
changeset 3750 f62625418bff
parent 2457 9deec258ab1a
child 3752 9f6f46dbe3ae
equal deleted inserted replaced
3749:fda6c1a37662 3750:f62625418bff
    21 # You should have received a copy of the GNU General Public License
    21 # You should have received a copy of the GNU General Public License
    22 # along with this program; if not, write to the Free Software
    22 # along with this program; if not, write to the Free Software
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    24 
    24 
    25 
    25 
    26 from __future__ import absolute_import
    26 
    27 from __future__ import print_function
    27 
    28 import os
    28 import os
    29 import re
    29 import re
    30 import datetime
    30 import datetime
    31 from types import FunctionType
    31 from types import FunctionType
    32 from xml.dom import minidom
    32 from xml.dom import minidom
    33 from future.builtins import round
    33 from future.builtins import round
    34 from six import string_types
    34 from six import string_types
    35 from past.builtins import long
    35 from past.builtins import int
    36 
    36 
    37 from xmlclass.xmlclass import *
    37 from xmlclass.xmlclass import *
    38 
    38 
    39 
    39 
    40 def GenerateDictFacets(facets):
    40 def GenerateDictFacets(facets):
    75         return text
    75         return text
    76     return generateXMLTextMethod
    76     return generateXMLTextMethod
    77 
    77 
    78 
    78 
    79 DEFAULT_FACETS = GenerateDictFacets(["pattern", "whiteSpace", "enumeration"])
    79 DEFAULT_FACETS = GenerateDictFacets(["pattern", "whiteSpace", "enumeration"])
    80 NUMBER_FACETS = GenerateDictFacets(DEFAULT_FACETS.keys() + ["maxInclusive", "maxExclusive", "minInclusive", "minExclusive"])
    80 NUMBER_FACETS = GenerateDictFacets(list(DEFAULT_FACETS.keys()) + ["maxInclusive", "maxExclusive", "minInclusive", "minExclusive"])
    81 DECIMAL_FACETS = GenerateDictFacets(NUMBER_FACETS.keys() + ["totalDigits", "fractionDigits"])
    81 DECIMAL_FACETS = GenerateDictFacets(list(NUMBER_FACETS.keys()) + ["totalDigits", "fractionDigits"])
    82 STRING_FACETS = GenerateDictFacets(DEFAULT_FACETS.keys() + ["length", "minLength", "maxLength"])
    82 STRING_FACETS = GenerateDictFacets(list(DEFAULT_FACETS.keys()) + ["length", "minLength", "maxLength"])
    83 
    83 
    84 ALL_FACETS = ["pattern", "whiteSpace", "enumeration", "maxInclusive",
    84 ALL_FACETS = ["pattern", "whiteSpace", "enumeration", "maxInclusive",
    85               "maxExclusive", "minInclusive", "minExclusive", "totalDigits",
    85               "maxExclusive", "minInclusive", "minExclusive", "totalDigits",
    86               "fractionDigits", "length", "minLength", "maxLength"]
    86               "fractionDigits", "length", "minLength", "maxLength"]
    87 
    87 
   202             if facettype in ["enumeration", "pattern"]:
   202             if facettype in ["enumeration", "pattern"]:
   203                 value = basetypeinfos["extract"](value, False)
   203                 value = basetypeinfos["extract"](value, False)
   204                 if len(facets) == 0:
   204                 if len(facets) == 0:
   205                     facets[facettype] = ([value], False)
   205                     facets[facettype] = ([value], False)
   206                     continue
   206                     continue
   207                 elif facets.keys() == [facettype]:
   207                 elif list(facets.keys()) == [facettype]:
   208                     facets[facettype][0].append(value)
   208                     facets[facettype][0].append(value)
   209                     continue
   209                     continue
   210                 else:
   210                 else:
   211                     raise ValueError("\"%s\" facet can't be defined with another facet type!" % facettype)
   211                     raise ValueError("\"%s\" facet can't be defined with another facet type!" % facettype)
   212             elif "enumeration" in facets:
   212             elif "enumeration" in facets:
   300                 elif basevalue is not None and value > basevalue:
   300                 elif basevalue is not None and value > basevalue:
   301                     raise ValueError("\"totalDigits\" can't be greater than \"totalDigits\" defined in base type!")
   301                     raise ValueError("\"totalDigits\" can't be greater than \"totalDigits\" defined in base type!")
   302             facets[facettype] = (value, facet.get("fixed", False))
   302             facets[facettype] = (value, facet.get("fixed", False))
   303 
   303 
   304         # Report not redefined facet from base type to new created type
   304         # Report not redefined facet from base type to new created type
   305         for facettype, facetvalue in basetypeinfos["facets"].items():
   305         for facettype, facetvalue in list(basetypeinfos["facets"].items()):
   306             if facettype not in facets:
   306             if facettype not in facets:
   307                 facets[facettype] = facetvalue
   307                 facets[facettype] = facetvalue
   308 
   308 
   309         # Generate extract value for new created type
   309         # Generate extract value for new created type
   310         def ExtractSimpleTypeValue(attr, extract=True):
   310         def ExtractSimpleTypeValue(attr, extract=True):
   311             value = basetypeinfos["extract"](attr, extract)
   311             value = basetypeinfos["extract"](attr, extract)
   312             for facetname, (facetvalue, _facetfixed) in facets.items():
   312             for facetname, (facetvalue, _facetfixed) in list(facets.items()):
   313                 if facetvalue is not None:
   313                 if facetvalue is not None:
   314                     if facetname == "enumeration" and value not in facetvalue:
   314                     if facetname == "enumeration" and value not in facetvalue:
   315                         raise ValueError("\"%s\" not in enumerated values" % value)
   315                         raise ValueError("\"%s\" not in enumerated values" % value)
   316                     elif facetname == "length" and len(value) != facetvalue:
   316                     elif facetname == "length" and len(value) != facetvalue:
   317                         raise ValueError("value must have a length of %d" % facetvalue)
   317                         raise ValueError("value must have a length of %d" % facetvalue)
   326                     elif facetname == "maxInclusive" and value > facetvalue:
   326                     elif facetname == "maxInclusive" and value > facetvalue:
   327                         raise ValueError("value must be lesser than or equal to %s" % str(facetvalue))
   327                         raise ValueError("value must be lesser than or equal to %s" % str(facetvalue))
   328                     elif facetname == "maxExclusive" and value >= facetvalue:
   328                     elif facetname == "maxExclusive" and value >= facetvalue:
   329                         raise ValueError("value must be lesser than %s" % str(facetvalue))
   329                         raise ValueError("value must be lesser than %s" % str(facetvalue))
   330                     elif facetname == "pattern":
   330                     elif facetname == "pattern":
   331                         model = re.compile("(?:%s)?$" % "|".join(map(lambda x: "(?:%s)" % x, facetvalue)))
   331                         model = re.compile("(?:%s)?$" % "|".join(["(?:%s)" % x for x in facetvalue]))
   332                         result = model.match(value)
   332                         result = model.match(value)
   333                         if result is None:
   333                         if result is None:
   334                             if len(facetvalue) > 1:
   334                             if len(facetvalue) > 1:
   335                                 raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue))
   335                                 raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue))
   336                             else:
   336                             else:
   341                         elif facetvalue == "collapse":
   341                         elif facetvalue == "collapse":
   342                             value = GetToken(value, False)
   342                             value = GetToken(value, False)
   343             return value
   343             return value
   344 
   344 
   345         def CheckSimpleTypeValue(value):
   345         def CheckSimpleTypeValue(value):
   346             for facetname, (facetvalue, _facetfixed) in facets.items():
   346             for facetname, (facetvalue, _facetfixed) in list(facets.items()):
   347                 if facetvalue is not None:
   347                 if facetvalue is not None:
   348                     if facetname == "enumeration" and value not in facetvalue:
   348                     if facetname == "enumeration" and value not in facetvalue:
   349                         return False
   349                         return False
   350                     elif facetname == "length" and len(value) != facetvalue:
   350                     elif facetname == "length" and len(value) != facetvalue:
   351                         return False
   351                         return False
   360                     elif facetname == "maxInclusive" and value > facetvalue:
   360                     elif facetname == "maxInclusive" and value > facetvalue:
   361                         return False
   361                         return False
   362                     elif facetname == "maxExclusive" and value >= facetvalue:
   362                     elif facetname == "maxExclusive" and value >= facetvalue:
   363                         return False
   363                         return False
   364                     elif facetname == "pattern":
   364                     elif facetname == "pattern":
   365                         model = re.compile("(?:%s)?$" % "|".join(map(lambda x: "(?:%s)" % x, facetvalue)))
   365                         model = re.compile("(?:%s)?$" % "|".join(["(?:%s)" % x for x in facetvalue]))
   366                         result = model.match(value)
   366                         result = model.match(value)
   367                         if result is None:
   367                         if result is None:
   368                             if len(facetvalue) > 1:
   368                             if len(facetvalue) > 1:
   369                                 raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue))
   369                                 raise ValueError("value doesn't follow any of the patterns %s" % ",".join(facetvalue))
   370                             else:
   370                             else:
   371                                 raise ValueError("value doesn't follow the pattern %s" % facetvalue[0])
   371                                 raise ValueError("value doesn't follow the pattern %s" % facetvalue[0])
   372             return True
   372             return True
   373 
   373 
   374         def SimpleTypeInitialValue():
   374         def SimpleTypeInitialValue():
   375             for facetname, (facetvalue, _facetfixed) in facets.items():
   375             for facetname, (facetvalue, _facetfixed) in list(facets.items()):
   376                 if facetvalue is not None:
   376                 if facetvalue is not None:
   377                     if facetname == "enumeration":
   377                     if facetname == "enumeration":
   378                         return facetvalue[0]
   378                         return facetvalue[0]
   379                     elif facetname == "length":
   379                     elif facetname == "length":
   380                         return " "*facetvalue
   380                         return " "*facetvalue
   513     attrs = []
   513     attrs = []
   514     attrnames = {}
   514     attrnames = {}
   515     if base is not None:
   515     if base is not None:
   516         basetypeinfos = factory.FindSchemaElement(base)
   516         basetypeinfos = factory.FindSchemaElement(base)
   517         if not isinstance(basetypeinfos, string_types) and basetypeinfos["type"] == COMPLEXTYPE:
   517         if not isinstance(basetypeinfos, string_types) and basetypeinfos["type"] == COMPLEXTYPE:
   518             attrnames = dict(map(lambda x: (x["name"], True), basetypeinfos["attributes"]))
   518             attrnames = dict([(x["name"], True) for x in basetypeinfos["attributes"]])
   519 
   519 
   520     for element in elements:
   520     for element in elements:
   521         if element["type"] == ATTRIBUTE:
   521         if element["type"] == ATTRIBUTE:
   522             if attrnames.get(element["name"], False):
   522             if attrnames.get(element["name"], False):
   523                 raise ValueError("\"%s\" attribute has been defined two times!" % element["name"])
   523                 raise ValueError("\"%s\" attribute has been defined two times!" % element["name"])
   994                 return result
   994                 return result
   995         return True
   995         return True
   996     elif isinstance(schema, dict):
   996     elif isinstance(schema, dict):
   997         if not isinstance(reference, dict) or len(schema) != len(reference):
   997         if not isinstance(reference, dict) or len(schema) != len(reference):
   998             return False
   998             return False
   999         for name, value in schema.items():
   999         for name, value in list(schema.items()):
  1000             ref_value = reference.get(name, None)
  1000             ref_value = reference.get(name, None)
  1001             if ref_value is None and value is not None:
  1001             if ref_value is None and value is not None:
  1002                 return False
  1002                 return False
  1003             result = CompareSchema(value, ref_value)
  1003             result = CompareSchema(value, ref_value)
  1004             if not result:
  1004             if not result:
  1059     def ParseSchema(self):
  1059     def ParseSchema(self):
  1060         for child in self.Document.childNodes:
  1060         for child in self.Document.childNodes:
  1061             if child.nodeType == self.Document.ELEMENT_NODE:
  1061             if child.nodeType == self.Document.ELEMENT_NODE:
  1062                 schema = child
  1062                 schema = child
  1063                 break
  1063                 break
  1064         for qualified_name, attr in schema._attrs.items():
  1064         for qualified_name, attr in list(schema._attrs.items()):
  1065             namespace, name = DecomposeQualifiedName(qualified_name)
  1065             namespace, name = DecomposeQualifiedName(qualified_name)
  1066             if namespace == "xmlns":
  1066             if namespace == "xmlns":
  1067                 value = GetAttributeValue(attr)
  1067                 value = GetAttributeValue(attr)
  1068                 self.DefinedNamespaces[value] = name
  1068                 self.DefinedNamespaces[value] = name
  1069                 self.NSMAP[name] = value
  1069                 self.NSMAP[name] = value
  2242         "basename": "base64Binary",
  2242         "basename": "base64Binary",
  2243         "extract": NotSupportedYet("base64Binary"),
  2243         "extract": NotSupportedYet("base64Binary"),
  2244         "facets": STRING_FACETS,
  2244         "facets": STRING_FACETS,
  2245         "generate": GenerateSimpleTypeXMLText(str),
  2245         "generate": GenerateSimpleTypeXMLText(str),
  2246         "initial": lambda: 0,
  2246         "initial": lambda: 0,
  2247         "check": lambda x: isinstance(x, (int, long))
  2247         "check": lambda x: isinstance(x, int)
  2248     },
  2248     },
  2249 
  2249 
  2250     "hexBinary": {
  2250     "hexBinary": {
  2251         "type": SIMPLETYPE,
  2251         "type": SIMPLETYPE,
  2252         "basename": "hexBinary",
  2252         "basename": "hexBinary",
  2253         "extract": GetHexInteger,
  2253         "extract": GetHexInteger,
  2254         "facets": STRING_FACETS,
  2254         "facets": STRING_FACETS,
  2255         "generate": GenerateSimpleTypeXMLText(lambda x: ("%."+str(int(round(len("%X" % x)/2.)*2))+"X") % x),
  2255         "generate": GenerateSimpleTypeXMLText(lambda x: ("%."+str(int(round(len("%X" % x)/2.)*2))+"X") % x),
  2256         "initial": lambda: 0,
  2256         "initial": lambda: 0,
  2257         "check": lambda x: isinstance(x, (int, long))
  2257         "check": lambda x: isinstance(x, int)
  2258     },
  2258     },
  2259 
  2259 
  2260     "integer": {
  2260     "integer": {
  2261         "type": SIMPLETYPE,
  2261         "type": SIMPLETYPE,
  2262         "basename": "integer",
  2262         "basename": "integer",