Ensures the schema is valid on initialisation.

Added method validateDoc.

Added support for xsd:import.

Added method getTargetNamespace and fixed method getTypeInNode so that amedes:User can inherit from yep:User.

More changes coming.
This commit is contained in:
sebd 2005-01-21 13:57:18 +00:00
parent f22b7455a8
commit 89902f54aa
1 changed files with 29 additions and 7 deletions

View File

@ -44,6 +44,14 @@ class Schema(elements.Element):
""" An XML Schema definition.
Defines the structure of an document, and specifically field types.
"""
_schemaContext = None
def __init__(self, *a, **b):
""" Initializes a libxml2 schema context, ensuring the schema itself is valid.
"""
super(Schema, self).__init__(*a, **b)
parserContext = self.node.doc.schemaNewDocParserCtxt()
self._schemaContext = parserContext.schemaParse()
def buildXformsModelContext(self, context):
if context.schemas is None:
context.schemas = SchemasContext(
@ -162,11 +170,11 @@ class Schema(elements.Element):
return globalType
def getIncludeLocations(self):
""" Returns the list of included schema locations.
""" Returns the list of included and imported schema locations.
"""
return [
node.content
for node in self.evaluateXpath("xsd:include/@schemaLocation")
for node in self.evaluateXpath("(xsd:include|xsd:import)/@schemaLocation")
]
def getSchemaAtLocation(self, schemaLocation):
@ -183,17 +191,23 @@ class Schema(elements.Element):
return None
return schemaHolder.getRootElement()
def getTargetNamespace(self):
""" Returns the target namespace uri.
"""
return self.node.prop("targetNamespace")
def getTypeInNode(self, value, node, name):
""" Returns a TypeContext for element or attribute "name".
Argument "value" is a ModelContext to be used as the context specimen.
Argument "node" is the context node (where to look for the element or attribute declaration).
"""
for typeNode in self.evaluateXpath("*[@name = '%s']" % name.replace("'", "'"), node):
name = name.replace("'", "'")
for typeNode in self.evaluateXpath("*[@name = '%s']" % name, node):
return self.newTypeContext(value, typeNode)
# if the supplied name has a namespace prefix, try without it
if ":" in name:
name = name[name.index(':') + 1:]
for typeNode in self.evaluateXpath("*[@name = '%s']" % name.replace("'", "'"), node):
targetNamespacePrefix = namespaces.getName(self.getTargetNamespace())
if name[:len(targetNamespacePrefix) + 1] == "%s:" % targetNamespacePrefix:
name = name[len(targetNamespacePrefix) + 1:]
for typeNode in self.evaluateXpath("*[@name = '%s']" % name, node):
return self.newTypeContext(value, typeNode)
def newContext(self, specimen, *attributes, **keywords):
@ -218,6 +232,14 @@ class Schema(elements.Element):
type.__class__ = typeClass
return TypeContext(type, value, previous = value)
def validateDoc(self, doc, options):
""" Validates a libxml2 document. Returns 0 on success.
"""
validationContext = self._schemaContext.schemaNewValidCtxt()
validationContext.schemaSetValidOptions(options)
return doc.schemaValidateDoc(validationContext)
class SchemaContext(stations.AbstractContext):
""" A Context with a Type as prototype and a ModelContext as specimen.