diff --git a/XMLSchema.py b/XMLSchema.py index 18f63fb..0dc5384 100755 --- a/XMLSchema.py +++ b/XMLSchema.py @@ -266,6 +266,7 @@ class DOMAdapter(DOMAdapterInterface): class XMLBase: """ These class variables are for string indentation. """ + tag = None __indent = 0 __rlock = RLock() @@ -431,6 +432,27 @@ class XMLSchemaComponent(XMLBase, MarkerInterface): and type(self.__class__.contents) == type(XMLSchemaComponent.contents)): raise RuntimeError, 'Bad type for a class variable in %s' %self.__class__ + def getItemTrace(self): + """Returns a node trace up to the item. + """ + item, path, name, ref = self, [], 'name', 'ref' + while isinstance(item, XMLSchema) is False: + attr = item.getAttribute(name) + if attr is None: + attr = item.getAttribute(ref) + if attr is None: path.append('<%s>' %(item.tag)) + else: path.append('<%s ref="%s">' %(item.tag, attr)) + else: + path.append('<%s name="%s">' %(item.tag,attr)) + item = item._parent() + try: + tns = item.getTargetNamespace() + except: + tns = '' + path.append('<%s targetNamespace="%s">' %(item.tag, tns)) + path.reverse() + return ''.join(path) + def getTargetNamespace(self): """return targetNamespace """ @@ -597,6 +619,7 @@ class WSDLToolsAdapter(XMLSchemaComponent): """WSDL Adapter to grab the attributes from the wsdl document node. """ attributes = {'name':None, 'targetNamespace':None} + tag = 'definitions' def __init__(self, wsdl): #XMLSchemaComponent.__init__(self, None) @@ -624,6 +647,7 @@ class Notation(XMLSchemaComponent): required = ['name', 'public'] attributes = {'id':None, 'name':None, 'public':None, 'system':None} contents = {'xsd':('annotation')} + tag = 'notation' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -656,6 +680,7 @@ class Annotation(XMLSchemaComponent): """ attributes = {'id':None} contents = {'xsd':('documentation', 'appinfo')} + tag = 'annotation' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -691,6 +716,7 @@ class Annotation(XMLSchemaComponent): """ attributes = {'source':None, 'xml:lang':None} contents = {'xsd':('mixed', 'any')} + tag = 'documentation' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -725,6 +751,7 @@ class Annotation(XMLSchemaComponent): """ attributes = {'source':None, 'anyURI':None} contents = {'xsd':('mixed', 'any')} + tag = 'appinfo' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -804,6 +831,7 @@ class XMLSchema(XMLSchemaComponent): 'attributeGroup', 'complexType', 'element', 'group',\ 'notation', 'simpleType', 'annotation')} empty_namespace = '' + tag = 'schema' def __init__(self, parent=None): """parent -- @@ -1066,6 +1094,7 @@ class XMLSchema(XMLSchemaComponent): 'namespace':None, 'schemaLocation':None} contents = {'xsd':['annotation']} + tag = 'import' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1123,6 +1152,7 @@ class XMLSchema(XMLSchemaComponent): attributes = {'id':None, 'schemaLocation':None} contents = {'xsd':['annotation']} + tag = 'include' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1147,10 +1177,7 @@ class XMLSchema(XMLSchemaComponent): and create a new Schema class instance. """ if not self._schema: - #schema = self._parent()._parent() schema = self._parent() - #self._schema = schema.getIncludeSchemas(\ - # self.attributes['schemaLocation']) self._schema = schema.getIncludeSchemas().get(\ self.attributes['schemaLocation'] ) @@ -1185,6 +1212,7 @@ class AttributeDeclaration(XMLSchemaComponent,\ 'default':None, 'fixed':None} contents = {'xsd':['annotation','simpleType']} + tag = 'attribute' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1277,6 +1305,7 @@ class AttributeWildCard(XMLSchemaComponent,\ 'namespace':'##any', 'processContents':'strict'} contents = {'xsd':['annotation']} + tag = 'anyAttribute' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1317,6 +1346,7 @@ class AttributeReference(XMLSchemaComponent,\ 'default':None, 'fixed':None} contents = {'xsd':['annotation']} + tag = 'attribute' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1351,6 +1381,7 @@ class AttributeGroupDefinition(XMLSchemaComponent,\ attributes = {'id':None, 'name':None} contents = {'xsd':['annotation']} + tag = 'attributeGroup' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1405,6 +1436,7 @@ class AttributeGroupReference(XMLSchemaComponent,\ attributes = {'id':None, 'ref':None} contents = {'xsd':['annotation']} + tag = 'attributeGroup' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1501,6 +1533,7 @@ class IdentityConstrants(XMLSchemaComponent): attributes = {'id':None, 'xpath':None} contents = {'xsd':['annotation']} + tag = 'selector' class Field(Constraint): """ @@ -1516,6 +1549,7 @@ class IdentityConstrants(XMLSchemaComponent): attributes = {'id':None, 'xpath':None} contents = {'xsd':['annotation']} + tag = 'field' class Unique(IdentityConstrants): @@ -1533,6 +1567,7 @@ class Unique(IdentityConstrants): attributes = {'id':None, 'name':None} contents = {'xsd':['annotation', 'selector', 'field']} + tag = 'unique' class Key(IdentityConstrants): @@ -1552,6 +1587,7 @@ class Key(IdentityConstrants): attributes = {'id':None, 'name':None} contents = {'xsd':['annotation', 'selector', 'field']} + tag = 'key' class KeyRef(IdentityConstrants): @@ -1571,6 +1607,7 @@ class KeyRef(IdentityConstrants): 'name':None, 'refer':None} contents = {'xsd':['annotation', 'selector', 'field']} + tag = 'keyref' class ElementDeclaration(XMLSchemaComponent,\ @@ -1609,6 +1646,7 @@ class ElementDeclaration(XMLSchemaComponent,\ 'final':lambda self: self._parent().getFinalDefault()} contents = {'xsd':['annotation', 'simpleType', 'complexType', 'key',\ 'keyref', 'unique']} + tag = 'element' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1704,6 +1742,7 @@ class ElementReference(XMLSchemaComponent,\ 'minOccurs':'1', 'maxOccurs':'1'} contents = {'xsd':['annotation']} + tag = 'element' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1744,6 +1783,7 @@ class ElementWildCard(LocalElementDeclaration,\ 'namespace':'##any', 'processContents':'strict'} contents = {'xsd':['annotation']} + tag = 'any' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1783,6 +1823,7 @@ class Sequence(XMLSchemaComponent,\ 'maxOccurs':'1'} contents = {'xsd':['annotation', 'element', 'group', 'choice', 'sequence',\ 'any']} + tag = 'sequence' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1839,6 +1880,7 @@ class All(XMLSchemaComponent,\ 'minOccurs':'1', 'maxOccurs':'1'} contents = {'xsd':['annotation', 'element']} + tag = 'all' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1888,6 +1930,7 @@ class Choice(XMLSchemaComponent,\ 'maxOccurs':'1'} contents = {'xsd':['annotation', 'element', 'group', 'choice', 'sequence',\ 'any']} + tag = 'choice' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1944,6 +1987,7 @@ class ModelGroupDefinition(XMLSchemaComponent,\ attributes = {'id':None, 'name':None} contents = {'xsd':['annotation', 'all', 'choice', 'sequence']} + tag = 'group' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -1995,6 +2039,7 @@ class ModelGroupReference(XMLSchemaComponent,\ 'minOccurs':'1', 'maxOccurs':'1'} contents = {'xsd':['annotation']} + tag = 'group' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -2045,6 +2090,7 @@ class ComplexType(XMLSchemaComponent,\ contents = {'xsd':['annotation', 'simpleContent', 'complexContent',\ 'group', 'all', 'choice', 'sequence', 'attribute', 'attributeGroup',\ 'anyAttribute', 'any']} + tag = 'complexType' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -2151,6 +2197,7 @@ class ComplexType(XMLSchemaComponent,\ attributes = {'id':None, 'mixed':0 } contents = {'xsd':['annotation', 'restriction', 'extension']} + tag = 'complexContent' class _DerivationBase(XMLSchemaComponent): """, @@ -2247,7 +2294,7 @@ class ComplexType(XMLSchemaComponent,\ annotation?, (group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute? """ - pass + tag = 'extension' class Restriction(_DerivationBase,\ RestrictionMarker): @@ -2262,7 +2309,7 @@ class ComplexType(XMLSchemaComponent,\ annotation?, (group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute? """ - pass + tag = 'restriction' class SimpleContent(_DerivedType,\ @@ -2278,6 +2325,7 @@ class ComplexType(XMLSchemaComponent,\ """ attributes = {'id':None} contents = {'xsd':['annotation', 'restriction', 'extension']} + tag = 'simpleContent' class Extension(XMLSchemaComponent,\ ExtensionMarker): @@ -2296,6 +2344,7 @@ class ComplexType(XMLSchemaComponent,\ 'base':None } contents = {'xsd':['annotation', 'attribute', 'attributeGroup', 'anyAttribute']} + tag = 'extension' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -2359,6 +2408,7 @@ class ComplexType(XMLSchemaComponent,\ 'base':None } contents = {'xsd':['annotation', 'simpleType', 'attribute',\ 'attributeGroup', 'anyAttribute'] + RestrictionMarker.facets} + tag = 'restriction' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -2422,6 +2472,7 @@ class LocalComplexType(ComplexType,\ required = [] attributes = {'id':None, 'mixed':0} + tag = 'complexType' class SimpleType(XMLSchemaComponent,\ @@ -2444,6 +2495,7 @@ class SimpleType(XMLSchemaComponent,\ 'name':None, 'final':lambda self: self._parent().getFinalDefault()} contents = {'xsd':['annotation', 'restriction', 'list', 'union']} + tag = 'simpleType' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -2490,6 +2542,7 @@ class SimpleType(XMLSchemaComponent,\ attributes = {'id':None, 'base':None } contents = {'xsd':['annotation', 'simpleType']+RestrictionMarker.facets} + tag = 'restriction' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -2532,6 +2585,7 @@ class SimpleType(XMLSchemaComponent,\ attributes = {'id':None, 'memberTypes':None } contents = {'xsd':['annotation', 'simpleType']} + tag = 'union' def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) @@ -2569,6 +2623,8 @@ class SimpleType(XMLSchemaComponent,\ attributes = {'id':None, 'itemType':None } contents = {'xsd':['annotation', 'simpleType']} + tag = 'list' + def __init__(self, parent): XMLSchemaComponent.__init__(self, parent) self.annotation = None @@ -2605,6 +2661,7 @@ class AnonymousSimpleType(SimpleType,\ """ required = [] attributes = {'id':None} + tag = 'simpleType' class Redefine: @@ -2614,7 +2671,8 @@ class Redefine: contents: """ - pass + tag = 'redefine' + ########################### ########################### @@ -2647,330 +2705,3 @@ class TypeDescriptionComponent(tupleClass): def getName(self): return self[1] - -''' -import string, types, base64, re -from Utility import DOM, Collection -from StringIO import StringIO - - -class SchemaReader: - """A SchemaReader creates XMLSchema objects from urls and xml data.""" - - def loadFromStream(self, file): - """Return an XMLSchema instance loaded from a file object.""" - document = DOM.loadDocument(file) - schema = XMLSchema() - schema.load(document) - return schema - - def loadFromString(self, data): - """Return an XMLSchema instance loaded from an xml string.""" - return self.loadFromStream(StringIO(data)) - - def loadFromURL(self, url): - """Return an XMLSchema instance loaded from the given url.""" - document = DOM.loadFromURL(url) - schema = XMLSchema() - schema.location = url - schema.load(document) - return schema - - def loadFromFile(self, filename): - """Return an XMLSchema instance loaded from the given file.""" - file = open(filename, 'rb') - try: schema = self.loadFromStream(file) - finally: file.close() - return schema - -class SchemaError(Exception): - pass - -class XMLSchema: - # This is temporary, for the benefit of WSDL until the real thing works. - def __init__(self, element): - self.targetNamespace = DOM.getAttr(element, 'targetNamespace') - self.element = element - -class realXMLSchema: - """A schema is a collection of schema components derived from one - or more schema documents, that is, one or more element - information items. It represents the abstract notion of a schema - rather than a single schema document (or other representation).""" - def __init__(self): - self.simpleTypes = Collection(self) - self.complexTypes = Collection(self) - self.attributes = Collection(self) - self.elements = Collection(self) - self.attrGroups = Collection(self) - self.idConstraints=None - self.modelGroups = None - self.notations = None - self.extensions = [] - - targetNamespace = None - attributeFormDefault = 'unqualified' - elementFormDefault = 'unqualified' - blockDefault = None - finalDefault = None - location = None - version = None - id = None - - def load(self, document): - if document.nodeType == document.DOCUMENT_NODE: - schema = DOM.getElement(document, 'schema', None, None) - else: - schema = document - if schema is None: - raise SchemaError('Missing element.') - - self.namespace = namespace = schema.namespaceURI - if not namespace in DOM.NS_XSD_ALL: - raise SchemaError( - 'Unknown XML schema namespace: %s.' % self.namespace - ) - - for attrname in ( - 'targetNamespace', 'attributeFormDefault', 'elementFormDefault', - 'blockDefault', 'finalDefault', 'version', 'id' - ): - value = DOM.getAttr(schema, attrname, None, None) - if value is not None: - setattr(self, attrname, value) - - - # Resolve imports and includes here? -## imported = {} -## while 1: -## imports = [] -## for element in DOM.getElements(definitions, 'import', NS_WSDL): -## location = DOM.getAttr(element, 'location') -## if not imported.has_key(location): -## imports.append(element) -## if not imports: -## break -## for element in imports: -## self._import(document, element) -## imported[location] = 1 - - for element in DOM.getElements(schema, None, None): - localName = element.localName - - if not DOM.nsUriMatch(element.namespaceURI, namespace): - self.extensions.append(element) - continue - - elif localName == 'message': - name = DOM.getAttr(element, 'name') - docs = GetDocumentation(element) - message = self.addMessage(name, docs) - parts = DOM.getElements(element, 'part', NS_WSDL) - message.load(parts) - continue - - def _import(self, document, element): - namespace = DOM.getAttr(element, 'namespace', default=None) - location = DOM.getAttr(element, 'location', default=None) - if namespace is None or location is None: - raise WSDLError( - 'Invalid import element (missing namespace or location).' - ) - - # Sort-of support relative locations to simplify unit testing. The - # WSDL specification actually doesn't allow relative URLs, so its - # ok that this only works with urls relative to the initial document. - location = urllib.basejoin(self.location, location) - - obimport = self.addImport(namespace, location) - obimport._loaded = 1 - - importdoc = DOM.loadFromURL(location) - try: - if location.find('#') > -1: - idref = location.split('#')[-1] - imported = DOM.getElementById(importdoc, idref) - else: - imported = importdoc.documentElement - if imported is None: - raise WSDLError( - 'Import target element not found for: %s' % location - ) - - imported_tns = DOM.getAttr(imported, 'targetNamespace') - importer_tns = namespace - - if imported_tns != importer_tns: - return - - if imported.localName == 'definitions': - imported_nodes = imported.childNodes - else: - imported_nodes = [imported] - parent = element.parentNode - for node in imported_nodes: - if node.nodeType != node.ELEMENT_NODE: - continue - child = DOM.importNode(document, node, 1) - parent.appendChild(child) - child.setAttribute('targetNamespace', importer_tns) - attrsNS = imported._attrsNS - for attrkey in attrsNS.keys(): - if attrkey[0] == DOM.NS_XMLNS: - attr = attrsNS[attrkey].cloneNode(1) - child.setAttributeNode(attr) - finally: - importdoc.unlink() - - -class Element: - """Common base class for element representation classes.""" - def __init__(self, name=None, documentation=''): - self.name = name - self.documentation = documentation - self.extensions = [] - - def addExtension(self, item): - self.extensions.append(item) - - -class SimpleTypeDefinition: - """Represents an xml schema simple type definition.""" - -class ComplexTypeDefinition: - """Represents an xml schema complex type definition.""" - -class AttributeDeclaration: - """Represents an xml schema attribute declaration.""" - -class ElementDeclaration: - """Represents an xml schema element declaration.""" - def __init__(self, name, type=None, targetNamespace=None): - self.name = name - - targetNamespace = None - annotation = None - nillable = 0 - abstract = 0 - default = None - fixed = None - scope = 'global' - type = None - form = 0 - # Things we will not worry about for now. - id_constraint_defs = None - sub_group_exclude = None - sub_group_affils = None - disallowed_subs = None - - - - - - - - - - -class AttributeGroupDefinition: - """Represents an xml schema attribute group definition.""" - -class IdentityConstraintDefinition: - """Represents an xml schema identity constraint definition.""" - -class ModelGroupDefinition: - """Represents an xml schema model group definition.""" - -class NotationDeclaration: - """Represents an xml schema notation declaration.""" - -class Annotation: - """Represents an xml schema annotation.""" - -class ModelGroup: - """Represents an xml schema model group.""" - -class Particle: - """Represents an xml schema particle.""" - -class WildCard: - """Represents an xml schema wildcard.""" - -class AttributeUse: - """Represents an xml schema attribute use.""" - - -class ElementComponent: - namespace = '' - name = '' - type = None - form = 'qualified | unqualified' - scope = 'global or complex def' - constraint = ('value', 'default | fixed') - nillable = 0 - id_constraint_defs = None - sub_group_affil = None - sub_group_exclusions = None - disallowed_subs = 'substitution, extension, restriction' - abstract = 0 - minOccurs = 1 - maxOccurs = 1 - ref = '' - -class AttributeThing: - name = '' - namespace = '' - typeName = '' - typeUri = '' - scope = 'global | local to complex def' - constraint = ('value:default', 'value:fixed') - use = 'optional | prohibited | required' - -class ElementDataType: - namespace = '' - name = '' - element_form = 'qualified | unqualified' - attr_form = None - type_name = '' - type_uri = '' - def __init__(self, name, namespace, type_name, type_uri): - self.namespace = namespace - self.name = name - # type may be anonymous... - self.type_name = type_name - self.type_uri = type_uri - - def checkValue(self, value, context): - # Delegate value checking to the type of the element. - typeref = (self.type_uri, self.type_name) - handler = context.serializer.getType(typeref) - return handler.checkValue(value, context) - - def serialize(self, name, namespace, value, context, **kwargs): - if context.check_values: - self.checkValue(value, context) - # Delegate serialization to the type of the element. - typeref = (self.type_uri, self.type_name) - handler = context.serializer.getType(typeref) - return handler.serialize(self.name, self.namespace, value, context) - - def deserialize(self, element, context): - if element_is_null(element, context): - return None - # Delegate deserialization to the type of the element. - typeref = (self.type_uri, self.type_name) - handler = context.serializer.getType(typeref) - return handler.deserialize(element, context) - - - -def parse_schema(data): - targetNS = '' - attributeFormDefault = 0 - elementFormDefault = 0 - blockDefault = '' - finalDefault = '' - language = None - version = None - id = '' -'''