Browse Source

----------------------------------------------------------------------

Modified Files:
 	XMLSchema.py -- fixed XMLSchemaComponent.setAttributes, added
		the needed getNamespace method to all DOMAdapters.  All
		changes are related to XML attribute handling.

 ----------------------------------------------------------------------
main
Joshua Boverhof 21 years ago
parent
commit
e50368f02a
1 changed files with 92 additions and 87 deletions
  1. +92
    -87
      XMLSchema.py

+ 92
- 87
XMLSchema.py View File

@@ -127,9 +127,10 @@ class SchemaError(Exception):
# DOM Utility Adapters # DOM Utility Adapters
########################## ##########################
class DOMAdapterInterface: class DOMAdapterInterface:
def hasattr(self, attr):
def hasattr(self, attr, ns=None):
"""return true if node has attribute """return true if node has attribute
attr - attribute to check for
attr -- attribute to check for
ns -- namespace of attribute, by default None
""" """
raise NotImplementedError, 'adapter method not implemented' raise NotImplementedError, 'adapter method not implemented'


@@ -149,6 +150,11 @@ class DOMAdapterInterface:
""" """
raise NotImplementedError, 'adapter method not implemented' raise NotImplementedError, 'adapter method not implemented'


def getNamespace(self, prefix):
"""returns namespace referenced by prefix.
"""
raise NotImplementedError, 'adapter method not implemented'

def getTagName(self): def getTagName(self):
"""returns tagName of node """returns tagName of node
""" """
@@ -180,14 +186,14 @@ class DOMAdapter(DOMAdapterInterface):
self.__node = node self.__node = node
self.__attributes = None self.__attributes = None


def hasattr(self, attr):
"""XXX assuming all xsd attributes not prefixed,
all others are. Should ask xmlInterface so
it can take care namespace mapping for
prefixed attributes
def hasattr(self, attr, ns=None):
"""attr -- attribute
ns -- optional namespace, None means unprefixed attribute.
""" """
if not self.__attributes: if not self.__attributes:
self.setAttributeDictionary() self.setAttributeDictionary()
if ns:
return self.__attributes.get(ns,{}).has_key(attr)
return self.__attributes.has_key(attr) return self.__attributes.has_key(attr)


def getContentList(self, *contents): def getContentList(self, *contents):
@@ -212,6 +218,23 @@ class DOMAdapter(DOMAdapterInterface):
def getTagName(self): def getTagName(self):
return self.__node.tagName return self.__node.tagName


def getNamespace(self, prefix):
"""prefix -- deference namespace prefix in node's context.
Ascends parent nodes until found.
"""
namespace = None
if prefix == 'xmlns':
namespace = DOM.findDefaultNS(prefix, self.__node)
else:
try:
namespace = DOM.findNamespaceURI(prefix, self.__node)
except DOMException, ex:
if prefix != 'xml':
raise SchemaError, '%s namespace not declared for %s'\
%(prefix, self.__node._get_tagName())
namespace = XMLNS
return namespace
def loadDocument(self, file): def loadDocument(self, file):
self.__node = DOM.loadDocument(file) self.__node = DOM.loadDocument(file)
if hasattr(self.__node, 'documentElement'): if hasattr(self.__node, 'documentElement'):
@@ -250,6 +273,9 @@ class XMLSchemaComponent(XMLBase):
Value can be a function for runtime dependencies. Value can be a function for runtime dependencies.
contents -- dict of namespace keyed content lists. contents -- dict of namespace keyed content lists.
'xsd' content of xsd namespace. 'xsd' content of xsd namespace.
xmlns_key -- key for declared xmlns namespace.
xmlns -- xmlns is special prefix for namespace dictionary
xml -- special xml prefix for xml namespace.
""" """
required = [] required = []
attributes = {} attributes = {}
@@ -257,12 +283,7 @@ class XMLSchemaComponent(XMLBase):
xmlns_key = '' xmlns_key = ''
xmlns = 'xmlns' xmlns = 'xmlns'
xml = 'xml' xml = 'xml'
xsd = 'xsd'
wsdl = 'wsdl'
soap = 'soap'
soapenc = 'soapenc'
mime = 'mime'
http = 'http'
#xsd = 'xsd'


def __init__(self, parent=None): def __init__(self, parent=None):
"""parent -- parent instance """parent -- parent instance
@@ -285,12 +306,10 @@ class XMLSchemaComponent(XMLBase):
""" """
parent = self parent = self
targetNamespace = 'targetNamespace' targetNamespace = 'targetNamespace'
tns = self.attributes[XMLSchemaComponent.xsd].get(targetNamespace)
tns = self.attributes.get(targetNamespace)
while not tns: while not tns:
parent = parent._parent() parent = parent._parent()
print parent
print parent.attributes[XMLSchemaComponent.xsd]
tns = parent.attributes[XMLSchemaComponent.xsd].get(targetNamespace)
tns = parent.attributes.get(targetNamespace)
return tns return tns


def getTypeDefinition(self, attribute): def getTypeDefinition(self, attribute):
@@ -312,7 +331,7 @@ class XMLSchemaComponent(XMLBase):
collection -- collection in parent Schema instance to search. collection -- collection in parent Schema instance to search.
""" """
obj = None obj = None
tdc = self.attributes[XMLSchemaComponent.xsd].get(attribute)
tdc = self.attributes.get(attribute)
if tdc: if tdc:
parent = GetSchema(self) parent = GetSchema(self)
if parent.targetNamespace == tdc.getTargetNamespace(): if parent.targetNamespace == tdc.getTargetNamespace():
@@ -323,90 +342,75 @@ class XMLSchemaComponent(XMLBase):
return obj return obj


def getXMLNS(self, prefix=None): def getXMLNS(self, prefix=None):
"""retrieve contents
empty string returns 'xmlns'
"""deference prefix or by default xmlns, returns namespace.
""" """
parent = self parent = self
ns = self.attributes[XMLSchemaComponent.xmlns].get(prefix)
ns = self.attributes[XMLSchemaComponent.xmlns].get(prefix or\
XMLSchemaComponent.xmlns_key)
while not ns: while not ns:
parent = parent._parent() parent = parent._parent()
ns = parent.attributes[XMLSchemaComponent.xmlns].get(prefix or XMLSchemaComponent.xmlns_key)
ns = parent.attributes[XMLSchemaComponent.xmlns].get(prefix or\
XMLSchemaComponent.xmlns_key)
return ns return ns


def getAttribute(self, attribute): def getAttribute(self, attribute):
"""return requested attribute or None """return requested attribute or None
""" """
return self.attributes[XMLSchemaComponent.xsd].get(attribute)
return self.attributes.get(attribute)
def setAttributes(self, node): def setAttributes(self, node):
"""Sets up attribute dictionary, checks for required attributes and """Sets up attribute dictionary, checks for required attributes and
sets default attribute values. attr is for default attribute values sets default attribute values. attr is for default attribute values
determined at runtime. determined at runtime.

attribute dictionary is prefix keyed by
xml
xmlns
xsd
wsdl
soap
all other keys are namespace values.
structure of attributes dictionary
['xmlns'][xmlns_key] -- xmlns namespace
['xmlns'][prefix] -- declared namespace prefix
[namespace][prefix] -- attributes declared in a namespace
[attribute] -- attributes w/o prefix, default namespaces do
not directly apply to attributes, ie Name can't collide
with QName.
""" """
self.attributes = {XMLSchemaComponent.xsd:{},\
XMLSchemaComponent.xmlns:{}}
self.attributes = {XMLSchemaComponent.xmlns:{}}
for k,v in node.getAttributeDictionary().items(): for k,v in node.getAttributeDictionary().items():
prefix,value = SplitQName(k) prefix,value = SplitQName(k)
if value == XMLSchemaComponent.xmlns: if value == XMLSchemaComponent.xmlns:
self.attributes[value][prefix or XMLSchemaComponent.xmlns_key] = v self.attributes[value][prefix or XMLSchemaComponent.xmlns_key] = v
elif prefix: elif prefix:
ns = node.getNamespace(prefix) ns = node.getNamespace(prefix)
if ns == XMLNS or prefix == XMLSchemaComponent.xml:
if not self.attributes.has_key(XMLSchemaComponent.xml):
self.attributes[XMLSchemaComponent.xml] = {}
self.attributes[XMLSchemaComponent.xml][k] = v
elif ns in SCHEMA.XSD_LIST:
self.attributes[XMLSchemaComponent.xsd][value] = v
elif ns == WSDL.BASE:
if not self.attributes.has_key(XMLSchemaComponent.wsdl):
self.attributes[XMLSchemaComponent.wsdl] = {}
self.attributes[XMLSchemaComponent.wsdl][value] = v
elif ns == WSDL.BIND_HTTP:
if not self.attributes.has_key(XMLSchemaComponent.http):
self.attributes[XMLSchemaComponent.http] = {}
self.attributes[XMLSchemaComponent.http][value] = v
elif ns == WSDL.BIND_MIME:
if not self.attributes.has_key(XMLSchemaComponent.mime):
self.attributes[XMLSchemaComponent.mime] = {}
self.attributes[XMLSchemaComponent.mime][value] = v
elif ns == WSDL.BIND_SOAP:
if not self.attributes.has_key(XMLSchemaComponent.soap):
self.attributes[XMLSchemaComponent.soap] = {}
self.attributes[XMLSchemaComponent.soap][value] = v
else:
self.attributes[ns][value] = v
if not ns:
raise
if not ns or not self.attributes.has_key(ns):
self.attributes[ns] = {}
else: else:
#UNPREFIXED Attribute
self.attributes[XMLSchemaComponent.xsd][value] = v
self.attributes[value] = v


self.__checkAttributes() self.__checkAttributes()
self.__setAttributeDefaults() self.__setAttributeDefaults()


#set QNames #set QNames
for k in ['type', 'element', 'base', 'ref', 'substitutionGroup', 'itemType']: for k in ['type', 'element', 'base', 'ref', 'substitutionGroup', 'itemType']:
if self.attributes[XMLSchemaComponent.xsd].has_key(k):
prefix, value = SplitQName(self.attributes[XMLSchemaComponent.xsd].get(k))
self.attributes[XMLSchemaComponent.xsd][k] = \
if self.attributes.has_key(k):
prefix, value = SplitQName(self.attributes.get(k))
self.attributes[k] = \
TypeDescriptionComponent((self.getXMLNS(prefix), value)) TypeDescriptionComponent((self.getXMLNS(prefix), value))


#Union, memberTypes is a whitespace separated list of QNames
if self.attributes[XMLSchemaComponent.xsd].has_key('memberTypes'):
qnames = self.attributes[XMLSchemaComponent.xsd]['memberTypes']
#Union, memberTypes is a whitespace separated list of QNames
for k in ['memberTypes']:
if self.attributes.has_key(k):
qnames = self.attributes[k]
self.attributes[k] = []
for qname in qnames.split():
prefix, value = SplitQName(qname)
self.attributes['memberTypes'].append(\
TypeDescriptionComponent(\
(self.getXMLNS(prefix), value)))


def getContents(self, node): def getContents(self, node):
"""retrieve xsd contents """retrieve xsd contents
""" """
return node.getContentList(*self.__class__.contents[XMLSchemaComponent.xsd])
#return node.getContentList(*self.__class__.contents[XMLSchemaComponent.xsd])
return node.getContentList(*self.__class__.contents['xsd'])


def __setAttributeDefaults(self): def __setAttributeDefaults(self):
"""Looks for default values for unset attributes. If """Looks for default values for unset attributes. If
@@ -414,11 +418,11 @@ class XMLSchemaComponent(XMLBase):
it must be defined as an instance variable. it must be defined as an instance variable.
""" """
for k,v in self.__class__.attributes.items(): for k,v in self.__class__.attributes.items():
if v and not self.attributes[XMLSchemaComponent.xsd].has_key(k):
if v and not self.attributes.has_key(k):
if isinstance(v, types.FunctionType): if isinstance(v, types.FunctionType):
self.attributes[XMLSchemaComponent.xsd][k] = v(self)
self.attributes[k] = v(self)
else: else:
self.attributes[XMLSchemaComponent.xsd][k] = v
self.attributes[k] = v


def __checkAttributes(self): def __checkAttributes(self):
"""Checks that required attributes have been defined, """Checks that required attributes have been defined,
@@ -426,13 +430,14 @@ class XMLSchemaComponent(XMLBase):
all defined attributes are legal. all defined attributes are legal.
""" """
for a in self.__class__.required: for a in self.__class__.required:
if not self.attributes[XMLSchemaComponent.xsd].has_key(a):
if not self.attributes.has_key(a):
raise SchemaError,\ raise SchemaError,\
'class instance %s, missing required attribute %s'\ 'class instance %s, missing required attribute %s'\
%(self.__class__, a) %(self.__class__, a)


for a in self.attributes[XMLSchemaComponent.xsd].keys():
if a not in self.__class__.attributes.keys():
for a in self.attributes.keys():
if (a != XMLSchemaComponent.xmlns) and\
a not in self.__class__.attributes.keys():
raise SchemaError, '%s, unknown attribute' %a raise SchemaError, '%s, unknown attribute' %a




@@ -772,8 +777,8 @@ class XMLSchema(XMLSchemaComponent):
""" """
self.targetNamespace = None self.targetNamespace = None
XMLSchemaComponent.__init__(self, parent) XMLSchemaComponent.__init__(self, parent)
f = lambda k: k.attributes[XMLSchemaComponent.xsd]['name']
ns = lambda k: k.attributes[XMLSchemaComponent.xsd]['namespace']
f = lambda k: k.attributes['name']
ns = lambda k: k.attributes['namespace']
self.includes = Collection(self, key=f) self.includes = Collection(self, key=f)
self.imports = Collection(self, key=ns) self.imports = Collection(self, key=ns)
self.elements = Collection(self, key=f) self.elements = Collection(self, key=f)
@@ -858,22 +863,22 @@ class XMLSchema(XMLSchemaComponent):
def getElementFormDefault(self): def getElementFormDefault(self):
"""return elementFormDefault attribute """return elementFormDefault attribute
""" """
return self.attributes[XMLSchemaComponent.xsd]['elementFormDefault']
return self.attributes.get('elementFormDefault')


def getAttributeFormDefault(self): def getAttributeFormDefault(self):
"""return attributeFormDefault attribute """return attributeFormDefault attribute
""" """
return self.attributes[XMLSchemaComponent.xsd]['attributeFormDefault']
return self.attributes.get('attributeFormDefault')


def getBlockDefault(self): def getBlockDefault(self):
"""return blockDefault attribute """return blockDefault attribute
""" """
return self.attributes[XMLSchemaComponent.xsd].get('blockDefault')
return self.attributes.get('blockDefault')


def getFinalDefault(self): def getFinalDefault(self):
"""return finalDefault attribute """return finalDefault attribute
""" """
return self.attributes[XMLSchemaComponent.xsd].get('finalDefault')
return self.attributes.get('finalDefault')


def load(self, node): def load(self, node):
self.setAttributes(node) self.setAttributes(node)
@@ -998,7 +1003,7 @@ class XMLSchema(XMLSchemaComponent):
self.setAttributes(node) self.setAttributes(node)
contents = self.getContents(node) contents = self.getContents(node)


if self.attributes[XMLSchemaComponent.xsd]['namespace'] == self._parent().attributes[XMLSchemaComponent.xsd]['targetNamespace']:
if self.attributes['namespace'] == self._parent().attributes['targetNamespace']:
raise SchemaError, 'namespace of schema and import match' raise SchemaError, 'namespace of schema and import match'


for i in contents: for i in contents:
@@ -1015,16 +1020,16 @@ class XMLSchema(XMLSchemaComponent):
and create a new Schema class instance, and keep a hard reference. and create a new Schema class instance, and keep a hard reference.
""" """
if not self._schema: if not self._schema:
schema = self._parent().getImportSchemas().get(self.attributes[XMLSchemaComponent.xsd]['namespace'])
ns = self.attributes['namespace']
schema = self._parent().getImportSchemas().get(ns)
if not schema and self._parent()._parent: if not schema and self._parent()._parent:
schema = self._parent()._parent().getImportSchemas().get(self.attributes[XMLSchemaComponent.xsd]['namespace'])
schema = self._parent()._parent().getImportSchemas().get(ns)
if not schema: if not schema:
if not self.attributes[XMLSchemaComponent.xsd].has_key('schemaLocation'):
raise SchemaError, 'namespace(%s) is unknown'\
%self.attributes[XMLSchemaComponent.xsd]['namespace']
if not self.attributes.has_key('schemaLocation'):
raise SchemaError, 'namespace(%s) is unknown' %ns


url = urllib.basejoin(self._parent().getBaseUrl(),\ url = urllib.basejoin(self._parent().getBaseUrl(),\
self.attributes[XMLSchemaComponent.xsd]['schemaLocation'])
self.attributes['schemaLocation'])
reader = SchemaReader() reader = SchemaReader()
reader._imports = self._parent().getImportSchemas() reader._imports = self._parent().getImportSchemas()
reader._includes = self._parent().getIncludeSchemas() reader._includes = self._parent().getIncludeSchemas()


Loading…
Cancel
Save