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:
parent
f22b7455a8
commit
89902f54aa
|
@ -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.
|
||||
|
|
Reference in New Issue