@@ -14,7 +14,7 @@
ident = "$Id$"
ident = "$Id$"
import types, weakref, sys
import types, weakref, sys, warnings
from Namespaces import XMLNS
from Namespaces import XMLNS
from Utility import DOM, DOMException, Collection, SplitQName, basejoin
from Utility import DOM, DOMException, Collection, SplitQName, basejoin
from StringIO import StringIO
from StringIO import StringIO
@@ -50,6 +50,9 @@ def GetSchema(component):
class SchemaReader:
class SchemaReader:
"""A SchemaReader creates XMLSchema objects from urls and xml data.
"""A SchemaReader creates XMLSchema objects from urls and xml data.
"""
"""
namespaceToSchema = {}
def __init__(self, domReader=None, base_url=None):
def __init__(self, domReader=None, base_url=None):
"""domReader -- class must implement DOMAdapterInterface
"""domReader -- class must implement DOMAdapterInterface
base_url -- base url string
base_url -- base url string
@@ -120,16 +123,17 @@ class SchemaReader:
"""
"""
return self.loadFromStream(StringIO(data))
return self.loadFromStream(StringIO(data))
def loadFromURL(self, url):
def loadFromURL(self, url, schema=None ):
"""Return an XMLSchema instance loaded from the given url.
"""Return an XMLSchema instance loaded from the given url.
url -- URL to dereference
url -- URL to dereference
schema -- Optional XMLSchema instance.
"""
"""
reader = self.__readerClass()
reader = self.__readerClass()
if self.__base_url:
if self.__base_url:
url = basejoin(self.__base_url,url)
url = basejoin(self.__base_url,url)
reader.loadFromURL(url)
reader.loadFromURL(url)
schema = XMLSchema()
schema = schema or XMLSchema()
schema.setBaseUrl(url)
schema.setBaseUrl(url)
schema.load(reader)
schema.load(reader)
self.__setIncludes(schema)
self.__setIncludes(schema)
@@ -1009,6 +1013,9 @@ class XMLSchema(XMLSchemaComponent):
schema -- schema instance
schema -- schema instance
_imported_schemas
_imported_schemas
"""
"""
print "XMLSchema(%s) ADD IMPORT SCHEMA: %s" \
%(self.targetNamespace, schema.targetNamespace)
if not isinstance(schema, XMLSchema):
if not isinstance(schema, XMLSchema):
raise TypeError, 'expecting a Schema instance'
raise TypeError, 'expecting a Schema instance'
if schema.targetNamespace != self.targetNamespace:
if schema.targetNamespace != self.targetNamespace:
@@ -1115,7 +1122,6 @@ class XMLSchema(XMLSchemaComponent):
self.setAttributes(node)
self.setAttributes(node)
self.targetNamespace = self.getTargetNamespace()
self.targetNamespace = self.getTargetNamespace()
for childNode in self.getContents(node):
for childNode in self.getContents(node):
component = SplitQName(childNode.getTagName())[1]
component = SplitQName(childNode.getTagName())[1]
@@ -1144,26 +1150,36 @@ class XMLSchema(XMLSchemaComponent):
v._parent = weakref.ref(self)
v._parent = weakref.ref(self)
getattr(self,collection)[k] = v
getattr(self,collection)[k] = v
else:
else:
print "Warning: Not keeping schema component."
warnings.warn("Not keeping schema component.")
elif component == 'import':
elif component == 'import':
slocd = SchemaReader.namespaceToSchema
tp = self.__class__.Import(self)
tp = self.__class__.Import(self)
tp.fromDom(childNode)
tp.fromDom(childNode)
import_ns = tp.getAttribute('namespace') or \
self.__class__.empty_namespace
if not self.getImportSchemas().has_key(import_ns) and \
tp.getAttribute('schemaLocation'):
self.addImportSchema(tp.getSchema())
import_ns = tp.getAttribute('namespace') or\
self.__class__.empty_namespace
schema = slocd.get(import_ns)
if schema is None:
schema = XMLSchema()
slocd[import_ns] = schema
tp.loadSchema(schema)
else:
tp._schema = schema
if self.getImportSchemas().has_key(import_ns):
warnings.warn(\
'Detected multiple imports of the namespace "%s" '\
%import_ns)
self.addImportSchema(schema)
# spec says can have multiple imports of same namespace
# but purpose of import is just dependency declaration.
self.imports[import_ns] = tp
self.imports[import_ns] = tp
elif component == 'redefine':
elif component == 'redefine':
# redefine not implemented yet
pass
warnings.warn('redefine is ignored')
elif component == 'annotation':
elif component == 'annotation':
# annotation not implemented yet
pass
warnings.warn('annotation is ignored')
elif component == 'attribute':
elif component == 'attribute':
tp = AttributeDeclaration(self)
tp = AttributeDeclaration(self)
tp.fromDom(childNode)
tp.fromDom(childNode)
@@ -1195,7 +1211,37 @@ class XMLSchema(XMLSchemaComponent):
else:
else:
break
break
# indx += 1
# slocd = SchemaReader.namespaceToSchema
#
# print "XMLSchema(%d): %s" %(id(self), self.targetNamespace)
#
# for node in imports:
# tp = self.__class__.Import(self)
# tp.fromDom(node)
#
# import_ns = tp.getAttribute('namespace') or \
# self.__class__.empty_namespace
#
# print "<import namespace=%s>" %import_ns
#
# schema = slocd.get(import_ns)
# if schema is None:
# schema = XMLSchema()
# slocd[import_ns] = schema
# tp.loadSchema(schema)
# else:
# tp._schema = schema
#
# if self.getImportSchemas().has_key(import_ns):
# warnings.warn(\
# 'Detected multiple imports of the namespace "%s",'+
# 'may cause problems if they have different schemaLocations.' %import_ns
# )
# raise RuntimeError, 'hi'
#
# self.addImportSchema(schema)
# self.imports[import_ns] = tp
class Import(XMLSchemaComponent):
class Import(XMLSchemaComponent):
"""<import>
"""<import>
@@ -1244,6 +1290,7 @@ class XMLSchema(XMLSchemaComponent):
schema = self._parent().getImportSchemas().get(ns)
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(ns)
schema = self._parent()._parent().getImportSchemas().get(ns)
if not schema:
if not schema:
url = self.attributes.get('schemaLocation')
url = self.attributes.get('schemaLocation')
if not url:
if not url:
@@ -1254,6 +1301,16 @@ class XMLSchema(XMLSchemaComponent):
reader._includes = self._parent().getIncludeSchemas()
reader._includes = self._parent().getIncludeSchemas()
self._schema = reader.loadFromURL(url)
self._schema = reader.loadFromURL(url)
return self._schema or schema
return self._schema or schema
def loadSchema(self, schema):
"""
"""
base_url = self._parent().getBaseUrl()
reader = SchemaReader(base_url=base_url)
reader._imports = self._parent().getImportSchemas()
reader._includes = self._parent().getIncludeSchemas()
self._schema = schema
reader.loadFromURL(self.attributes.get('schemaLocation'), schema)
class Include(XMLSchemaComponent):
class Include(XMLSchemaComponent):