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