# HG changeset patch # User lbessard # Date 1200996049 -3600 # Node ID dcfe7c07ba1c3b97a8948cda9544759cab7c27cf # Parent aaa80b48beade8695c824c164561001793cc5b91 Removing minixsv (unused with new version of xmlclass) diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/datatypes.xsd --- a/minixsv/datatypes.xsd Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1264 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]> - - - - - - - The schema corresponding to this document is normative, - with respect to the syntactic constraints it expresses in the - XML Schema language. The documentation (within <documentation> - elements) below, is not normative, but rather highlights important - aspects of the W3C Recommendation of which this is a part - - - - - - First the built-in primitive datatypes. These definitions are for - information only, the real built-in definitions are magic. Note in - particular that there is no type named 'anySimpleType'. The - primitives should really be derived from no type at all, and - anySimpleType should be derived as a union of all the primitives. - - - - For each built-in datatype in this schema (both primitive and - derived) can be uniquely addressed via a URI constructed - as follows: - 1) the base URI is the URI of the XML Schema namespace - 2) the fragment identifier is the name of the datatype - - For example, to address the int datatype, the URI is: - - http://www.w3.org/2001/XMLSchema#int - - Additionally, each facet definition element can be uniquely - addressed via a URI constructed as follows: - 1) the base URI is the URI of the XML Schema namespace - 2) the fragment identifier is the name of the facet - - For example, to address the maxInclusive facet, the URI is: - - http://www.w3.org/2001/XMLSchema#maxInclusive - - Additionally, each facet usage in a built-in datatype definition - can be uniquely addressed via a URI constructed as follows: - 1) the base URI is the URI of the XML Schema namespace - 2) the fragment identifier is the name of the datatype, followed - by a period (".") followed by the name of the facet - - For example, to address the usage of the maxInclusive facet in - the definition of int, the URI is: - - http://www.w3.org/2001/XMLSchema#int.maxInclusive - - - - - - - - - - - - - - - Now the derived primitive types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - pattern specifies the content of section 2.12 of XML 1.0e2 - and RFC 1766 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - pattern matches production 7 from the XML spec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - pattern matches production 5 from the XML spec - - - - - - - - - - - - - - - pattern matches production 4 from the Namespaces in XML spec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A utility type, not for public use - - - - - - - - - - - - - - - - - - - - - - #all or (possibly empty) subset of {restriction, union, list} - - - A utility type, not for public use - - - - - - - - - - - - - - - - - - - - - - - - - - Can be restricted to required or forbidden - - - - - - - - - - - - - - - - - - Required at the top level - - - - - - - - - - - - - - - - - - Forbidden when nested - - - - - - - - - - - - - - - - - - We should use a substitution group for facets, but - that's ruled out because it would allow users to - add their own, which we're not ready for yet. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - base attribute and simpleType child are mutually - exclusive, but one or other is required - - - - - - - - - - - - - - - - itemType attribute and simpleType child are mutually - exclusive, but one or other is required - - - - - - - - - - - - - - - - - - memberTypes attribute must be non-empty or there must be - at least one simpleType child - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/datatypes2.xsd --- a/minixsv/datatypes2.xsd Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1264 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]> - - - - - - - The schema corresponding to this document is normative, - with respect to the syntactic constraints it expresses in the - XML Schema language. The documentation (within <documentation> - elements) below, is not normative, but rather highlights important - aspects of the W3C Recommendation of which this is a part - - - - - - First the built-in primitive datatypes. These definitions are for - information only, the real built-in definitions are magic. Note in - particular that there is no type named 'anySimpleType'. The - primitives should really be derived from no type at all, and - anySimpleType should be derived as a union of all the primitives. - - - - For each built-in datatype in this schema (both primitive and - derived) can be uniquely addressed via a URI constructed - as follows: - 1) the base URI is the URI of the XML Schema namespace - 2) the fragment identifier is the name of the datatype - - For example, to address the int datatype, the URI is: - - http://www.w3.org/2001/XMLSchema#int - - Additionally, each facet definition element can be uniquely - addressed via a URI constructed as follows: - 1) the base URI is the URI of the XML Schema namespace - 2) the fragment identifier is the name of the facet - - For example, to address the maxInclusive facet, the URI is: - - http://www.w3.org/2001/XMLSchema#maxInclusive - - Additionally, each facet usage in a built-in datatype definition - can be uniquely addressed via a URI constructed as follows: - 1) the base URI is the URI of the XML Schema namespace - 2) the fragment identifier is the name of the datatype, followed - by a period (".") followed by the name of the facet - - For example, to address the usage of the maxInclusive facet in - the definition of int, the URI is: - - http://www.w3.org/2001/XMLSchema#int.maxInclusive - - - - - - - - - - - - - - - Now the derived primitive types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - pattern specifies the content of section 2.12 of XML 1.0e2 - and RFC 1766 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - pattern matches production 7 from the XML spec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - pattern matches production 5 from the XML spec - - - - - - - - - - - - - - - pattern matches production 4 from the Namespaces in XML spec - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A utility type, not for public use - - - - - - - - - - - - - - - - - - - - - - #all or (possibly empty) subset of {restriction, union, list} - - - A utility type, not for public use - - - - - - - - - - - - - - - - - - - - - - - - - - Can be restricted to required or forbidden - - - - - - - - - - - - - - - - - - Required at the top level - - - - - - - - - - - - - - - - - - Forbidden when nested - - - - - - - - - - - - - - - - - - We should use a substitution group for facets, but - that's ruled out because it would allow users to - add their own, which we're not ready for yet. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - base attribute and simpleType child are mutually - exclusive, but one or other is required - - - - - - - - - - - - - - - - itemType attribute and simpleType child are mutually - exclusive, but one or other is required - - - - - - - - - - - - - - - - - - memberTypes attribute must be non-empty or there must be - at least one simpleType child - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/elemtreeif.py --- a/minixsv/elemtreeif.py Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,217 +0,0 @@ -# -# minixsv, Release 0.3 -# file: elemtreeif.py -# -# XML interface class to elementtree toolkit by Fredrik Lundh -# -# history: -# 2004-09-09 rl created -# 2004-09-22 rl XML interface classes completely re-designed -# 2004-09-23 rl added filename and line number support -# 2004-09-29 rl URL processing added -# 2004-10-01 rl URL processing improved -# 2004-10-12 rl XML text processing added -# -# Copyright (c) 2004 by Roland Leuthe. All rights reserved. -# -# -------------------------------------------------------------------- -# The minixsv XML schema validator is -# -# Copyright (c) 2004 by Roland Leuthe -# -# By obtaining, using, and/or copying this software and/or its -# associated documentation, you agree that you have read, understood, -# and will comply with the following terms and conditions: -# -# Permission to use, copy, modify, and distribute this software and -# its associated documentation for any purpose and without fee is -# hereby granted, provided that the above copyright notice appears in -# all copies, and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of -# the author not be used in advertising or publicity -# pertaining to distribution of the software without specific, written -# prior permission. -# -# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD -# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- -# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -# OF THIS SOFTWARE. -# -------------------------------------------------------------------- - - -import urllib -import urlparse -from xmlifbase import * -from xml.parsers.expat import ExpatError -from elementtree.ElementTree import * - -######################################################### -# Derived interface class for elementtree toolkit - -class ElementTreeInterface (XmlInterfaceBase): - ##################################################### - # for description of the interface methods see xmlifbase.py - ##################################################### - - def __init__ (self, verbose): - XmlInterfaceBase.__init__ (self, verbose) - if self.verbose: - print "Using elementtree interface module..." - - - def parse (self, file, baseUrl): - url = self._convertToUrl(file) - absUrl = self._convertToAbsUrl (url, baseUrl) - fp = urllib.urlopen (absUrl) - try: - tree = ElementTree() - parser = ExtXMLTreeBuilder(file, url, absUrl) - tree.parse(fp, parser) - finally: - fp.close() - - return TreeWrapper(self, tree) - - - def parseString (self, text): - parser = ExtXMLTreeBuilder("", "", "") - parser.feed(text) - return TreeWrapper (self, ElementTree(parser.close())) - - -######################################################### -# Wrapper class for ElementTree class - -class TreeWrapper (TreeWrapperBase): - - def getRootNode (self): - return ElementWrapper(self.xmlIf, self, self.tree.getroot()) - - - def insertSubtree (self, nextSiblingWrapper, file, baseUrl): - subTreeWrapper = self.xmlIf.extParse (file, baseUrl) - assert self.getRootNode().getTagName() == subTreeWrapper.getRootNode().getTagName(),\ - "%s: line %d: root node of include file %s does not match!" %(self.getRootNode().getUrl(), self.getRootNode().getStartLineNumber(), file) - - if nextSiblingWrapper != None: - insertIndex = self.tree.getroot().getchildren().index (nextSiblingWrapper.element) - else: - insertIndex = 0 - elementWrapperList = subTreeWrapper.getRootNode().getChildren() - elementWrapperList.reverse() - for elementWrapper in elementWrapperList: - self.tree.getroot().insert (insertIndex, elementWrapper.element) - - -######################################################### -# Wrapper class for Element class - -class ElementWrapper (ElementWrapperBase): - - def getTagName (self): - return self.element.tag - - - def getChildren (self, filterTag=None): - if filterTag in (None, '*'): - children = self.element.getchildren() - else: - children = self.element.findall(filterTag) - - return map(lambda element: ElementWrapper(self.xmlIf, self.treeWrapper, element), children) - - - def getFirstChild (self, filterTag=None): - # replace base method (performance optimized) - if filterTag in (None, '*'): - children = self.element.getchildren() - if children != []: - element = children[0] - else: - element = None - else: - element = self.element.find(filterTag) - - if element != None: - return ElementWrapper(self.xmlIf, self.treeWrapper, element) - else: - return None - - - def getElementsByTagName (self, filterTag=None): - if filterTag == '*': - filterTag = None - elements = self.element.getiterator (filterTag) - - return map(lambda element: ElementWrapper(self.xmlIf, self.treeWrapper, element), elements) - - - def removeChild (self, childElementWrapper): - self.element.remove (childElementWrapper.element) - - - def getAttributeDict (self): - return self.element.attrib - - - def getAttribute (self, attributeName): - if self.element.attrib.has_key(attributeName): - return self.element.attrib[attributeName] - else: - return None - - - def hasAttribute (self, attributeName): - return self.element.attrib.has_key(attributeName) - - - def setAttribute (self, attributeName, attributeValue): - self.element.attrib[attributeName] = attributeValue - - - ############################################################### - # Caution! Currently returns only the element value until the first - # child element!! - def getElementValue (self): - if self.element.text != None: - return self.element.text - else: - return "" - - - ############################################################### - # Caution! Currently only sets the element value until the first - # child element!! - def setElementValue (self, value): - self.element.text = value - - -################################################### -# Element tree builder class derived from XMLTreeBuilder -# extended to store related line numbers in the Element object - -class ExtXMLTreeBuilder (XMLTreeBuilder): - def __init__(self, filePath, url, absUrl): - self.filePath = filePath - self.url = url - self.absUrl = absUrl - XMLTreeBuilder.__init__(self) - - def _start(self, tag, attrib_in): - element = XMLTreeBuilder._start(self, tag, attrib_in) - element.filePath = self.filePath - element.url = self.url - element.absUrl = self.absUrl - element.startLineNumber = self._parser.ErrorLineNumber - return element - - def _end(self, tag): - element = XMLTreeBuilder._end(self, tag) - element.endLineNumber = self._parser.ErrorLineNumber - return element - - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/minidomif.py --- a/minixsv/minidomif.py Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,218 +0,0 @@ -# -# # minixsv, Release 0.3 -# file: minidomif.py -# -# XML interface class to minidom -# -# history: -# 2004-09-09 rl created -# 2004-09-22 rl XML interface classes completely re-designed -# 2004-09-23 rl added filename and line number support -# 2004-09-29 rl URL processing added -# 2004-10-01 rl URL processing improved -# 2004-10-12 rl XML text processing added -# -# Copyright (c) 2004 by Roland Leuthe. All rights reserved. -# -# -------------------------------------------------------------------- -# The minixsv XML schema validator is -# -# Copyright (c) 2004 by Roland Leuthe -# -# By obtaining, using, and/or copying this software and/or its -# associated documentation, you agree that you have read, understood, -# and will comply with the following terms and conditions: -# -# Permission to use, copy, modify, and distribute this software and -# its associated documentation for any purpose and without fee is -# hereby granted, provided that the above copyright notice appears in -# all copies, and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of -# the author not be used in advertising or publicity -# pertaining to distribution of the software without specific, written -# prior permission. -# -# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD -# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- -# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -# OF THIS SOFTWARE. -# -------------------------------------------------------------------- - -import urllib -from xmlifbase import * -from xml.parsers.expat import ExpatError -from xml.dom.expatbuilder import ExpatBuilderNS -from xml.dom.minidom import * - - -class MiniDomInterface (XmlInterfaceBase): - ##################################################### - # for description of the interface methods see xmlifbase.py - ##################################################### - - def __init__ (self, verbose): - XmlInterfaceBase.__init__ (self, verbose) - if self.verbose: - print "Using minidom interface module..." - - - def parse (self, file, baseUrl): - url = self._convertToUrl(file) - absUrl = self._convertToAbsUrl (url, baseUrl) - fp = urllib.urlopen (absUrl) - try: - builder = ExtExpatBuilderNS(file, url, absUrl) - tree = builder.parseFile(fp) - finally: - fp.close() - - return TreeWrapper(self, tree) - - - def parseString (self, text): - builder = ExtExpatBuilderNS("", "", "") - tree = builder.parseString (text) - return TreeWrapper (self, tree) - - -######################################################### -# Wrapper class for minidom.Document class - -class TreeWrapper (TreeWrapperBase): - - def getRootNode (self): - return ElementWrapper (self.xmlIf, self, self.tree.documentElement) - - def insertSubtree (self, nextSiblingWrapper, file, baseUrl): - subTreeWrapper = self.xmlIf.extParse (file, baseUrl) - assert self.getRootNode().getLocalName() == subTreeWrapper.getRootNode().getLocalName(),\ - "%s: line %d: root node of include file %s does not match!" %(self.getRootNode().getUrl(), self.getRootNode().getStartLineNumber(), file) - - elementWrapperList = subTreeWrapper.getRootNode().getChildren() - for elementWrapper in elementWrapperList: - if nextSiblingWrapper != None: - self.tree.documentElement.insertBefore(elementWrapper.element, nextSiblingWrapper.element) - else: - self.tree.documentElement.appendChild(elementWrapper.element) - - -######################################################### -# Wrapper class for minidom.Document class - -class ElementWrapper (ElementWrapperBase): - - def getTagName (self): - return self.element.tagName - - - def getLocalName (self): - # base method replaced (optimized method) - return self.element.localName - - - def getNamespaceURI (self): - # base method replaced (optimized method) - return self.element.namespaceURI - - - def getChildren (self, filterTag=None): - return map(lambda element: ElementWrapper(self.xmlIf, self.treeWrapper, element), self._getElemNodes(filterTag)) - - - def getElementsByTagName (self, filterTag=None): - if filterTag == None: - filterTag = '*' - return map(lambda element: ElementWrapper(self.xmlIf, self.treeWrapper, element), self.element.getElementsByTagName(filterTag)) - - - def removeChild (self, childElementWrapper): - self.element.removeChild(childElementWrapper.element) - - - def getAttributeDict (self): - """Return dictionary of attributes""" - attribDict = {} - for attrName, attrValue in self.element.attributes.items(): - attribDict[attrName] = attrValue - return attribDict - - - def getAttribute (self, attributeName): - if self.element.attributes.has_key (attributeName): - return self.element.getAttribute (attributeName) - else: - return None - - - def hasAttribute (self, attributeName): - return self.element.attributes.has_key (attributeName) - - - def setAttribute (self, attributeName, attributeValue): - if not self.hasAttribute(attributeName): - self.element.setAttributeNode (self.treeWrapper.tree.createAttribute (attributeName)) - self.element.setAttribute(attributeName, attributeValue) - - - ############################################################### - # Caution! Currently returns only the first text node!! - def getElementValue (self): - textNodes = self._getTextNodes () - if textNodes: - return textNodes[0].data - else: - return "" - - - ############################################################### - # Caution! Currently only sets the first text node!! - def setElementValue (self, value): - textNodes = self._getTextNodes() - if textNodes: - textNodes[0].data = value - - - ############################################################### - # PRIVATE methods - ############################################################### - - def _getTextNodes (self): - """Return list of TEXT nodes.""" - return filter (lambda e: (e.nodeType == Node.TEXT_NODE), # - only TEXT-NODES - self.element.childNodes) # from element's child nodes - - - def _getElemNodes (self, filterTag): - """Return list of ELEMENT nodes and check for tag name (if given).""" - return filter (lambda e: (e.nodeType == Node.ELEMENT_NODE) and # - only ELEMENTs - (not filterTag or filterTag == '*' or e.tagName == filterTag), # - if tagName given --> check tagName - self.element.childNodes) # from element's nodes - - - -################################################### -# Expat builder class derived from ExpatBuilderNS -# extended to store related line numbers in the node object - -class ExtExpatBuilderNS (ExpatBuilderNS): - def __init__ (self, filePath, url, absUrl): - self.filePath = filePath - self.url = url - self.absUrl = absUrl - ExpatBuilderNS.__init__(self) - - def start_element_handler(self, name, attributes): - ExpatBuilderNS.start_element_handler(self, name, attributes) - self.curNode.url = self.url - self.curNode.absUrl = self.absUrl - self.curNode.filePath = self.filePath - self.curNode.startLineNumber = self.getParser().ErrorLineNumber - - def end_element_handler(self, name): - self.curNode.endLineNumber = self.getParser().ErrorLineNumber - ExpatBuilderNS.end_element_handler(self, name) - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/pyxsval.py --- a/minixsv/pyxsval.py Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,283 +0,0 @@ -# -# minixsv, Release 0.3 -# file: pyxsval.py -# -# API for XML schema validator -# -# history: -# 2004-09-09 rl created -# 2004-09-29 rl adapted to re-designed XML interface classes, -# ErrorHandler separated, URL processing added, some bugs fixed -# 2004-10-07 rl Validator classes extracted into separate files -# 2004-10-12 rl API re-worked, XML text processing added -# -# Copyright (c) 2004 by Roland Leuthe. All rights reserved. -# -# -------------------------------------------------------------------- -# The minixsv XML schema validator is -# -# Copyright (c) 2004 by Roland Leuthe -# -# By obtaining, using, and/or copying this software and/or its -# associated documentation, you agree that you have read, understood, -# and will comply with the following terms and conditions: -# -# Permission to use, copy, modify, and distribute this software and -# its associated documentation for any purpose and without fee is -# hereby granted, provided that the above copyright notice appears in -# all copies, and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of -# the author not be used in advertising or publicity -# pertaining to distribution of the software without specific, written -# prior permission. -# -# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD -# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- -# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -# OF THIS SOFTWARE. -# -------------------------------------------------------------------- - -__all__ = [ - # public symbols - "parseAndValidate", - "parseAndValidateString", - "parseAndValidateXmlInput", - "parseAndValidateXmlInputString", - "parseAndValidateXmlSchema", - "parseAndValidateXmlSchemaString", - "XsValidator", - "XMLIF_MINIDOM", - "XMLIF_ELEMENTTREE" - ] - - -from xsvalErrorHandler import * -from xsvalBase import XsValBase -from xsvalSchema import XsValSchema - - -XMLIF_MINIDOM = "XMLIF_MINIDOM" -XMLIF_ELEMENTTREE = "XMLIF_ELEMENTTREE" - - -_XS_VAL_DEFAULT_ERROR_LIMIT = 20 - -_OWNDIR = os.path.dirname(__file__) - - -######################################## -# convenience function for validating -# 1. XML schema file -# 2. XML input file -# If xsdFile is specified, it will be used for validation -# If xsdFile=None, the schemaLocation attribute is expected in the root tag of the XML input file -# -def parseAndValidate (inputFile, xsdFile=None, **kw): - return parseAndValidateXmlInput (inputFile, xsdFile, 1, **kw) - - -######################################## -# convenience function for validating -# 1. text string containing the XML schema -# 2. text string containing the XML input -# If xsdText is given, it will be used for validation -# If xsdText=None, the schemaLocation attribute is expected in the root tag of the XML input -# -def parseAndValidateString (inputText, xsdText=None, **kw): - return parseAndValidateXmlInputString (inputText, xsdText, 1, **kw) - - -######################################## -# factory for validating -# 1. XML schema file (only if validateSchema=1) -# 2. XML input file -# If xsdFile is specified, it will be used for validation -# If xsdFile=None, the schemaLocation attribute is expected in the root tag of the XML input file -# -def parseAndValidateXmlInput (inputFile, xsdFile=None, validateSchema=0, **kw): - xsValidator = XsValidator (**kw) - # parse XML input file - inputTreeWrapper = xsValidator.parse (inputFile) - # validate XML input file - return xsValidator.validateXmlInput (inputFile, inputTreeWrapper, xsdFile, validateSchema) - - -######################################## -# factory for validating -# 1. text string containing the XML schema (only if validateSchema=1) -# 2. text string containing the XML input -# If xsdText is given, it will be used for validation -# If xsdText=None, the schemaLocation attribute is expected in the root tag of the XML input -# -def parseAndValidateXmlInputString (inputText, xsdText=None, validateSchema=0, **kw): - xsValidator = XsValidator (**kw) - # parse XML input text string - inputTreeWrapper = xsValidator.parseString (inputText) - # validate XML input text string - return xsValidator.validateXmlInputString (inputTreeWrapper, xsdText, validateSchema) - - -######################################## -# factory for validating only given XML schema file -# -def parseAndValidateXmlSchema (xsdFile, **kw): - xsValidator = XsValidator (**kw) - # parse XML schema file - xsdTreeWrapper = xsValidator.parse (xsdFile) - # validate XML schema file - return xsValidator.validateXmlSchema (xsdFile, xsdTreeWrapper) - - -######################################## -# factory for validating only given XML schema file -# -def parseAndValidateXmlSchemaString (xsdText, **kw): - xsValidator = XsValidator (**kw) - # parse XML schema - xsdTreeWrapper = xsValidator.parseString (xsdText) - # validate XML schema - return xsValidator.validateXmlSchema ("", xsdTreeWrapper) - - -######################################## -# XML schema validator class -# -class XsValidator: - def __init__(self, xmlIfClass=XMLIF_MINIDOM, - warningProc=IGNORE_WARNINGS, errorLimit=_XS_VAL_DEFAULT_ERROR_LIMIT, verbose=0): - - self.warningProc = warningProc - self.errorLimit = errorLimit - self.verbose = verbose - - # enable interface to minidom - if xmlIfClass == XMLIF_MINIDOM: - import minidomif - self.xmlIf = minidomif.MiniDomInterface(verbose) - - # enable interface to elementtree - elif xmlIfClass == XMLIF_ELEMENTTREE: - import elemtreeif - self.xmlIf = elemtreeif.ElementTreeInterface(verbose) - - # create error handler - self.errorHandler = ErrorHandler (errorLimit, warningProc, verbose) - - - ######################################## - # parse XML file - # 'file' may be a filepath or an URI - # - def parse (self, file, baseUrl=""): - try: - self._verbosePrint ("Parsing %s..." %(file)) - treeWrapper = self.xmlIf.extParse(file, baseUrl) - except AssertionError, errstr: - self.errorHandler.raiseError (errstr) - return treeWrapper - - - ######################################## - # parse text string containing XML - # - def parseString (self, text): - try: - self._verbosePrint ("Parsing XML text string...") - treeWrapper = self.xmlIf.extParseString(text) - except AssertionError, errstr: - self.errorHandler.raiseError (errstr) - return treeWrapper - - - ######################################## - # validate XML input - # - def validateXmlInput (self, xmlInputFile, inputTreeWrapper, xsdFile=None, validateSchema=0): - # parse XML schema file - if xsdFile != None: - xsdTreeWrapper = self.parse (xsdFile) - else: - # a schemaLocation attribute is expected in the root tag of the XML input file - xsdFile = self._retrieveReferencedXsdFile (inputTreeWrapper) - xsdTreeWrapper = self.parse (xsdFile, inputTreeWrapper.getRootNode().getAbsUrl()) - - return self._validateXmlInput (xmlInputFile, xsdFile, inputTreeWrapper, xsdTreeWrapper, validateSchema) - - - ######################################## - # validate XML input - # - def validateXmlInputString (self, inputTreeWrapper, xsdText=None, validateSchema=0): - # parse XML schema file - if xsdText != None: - xsdFile = "schema text" - xsdTreeWrapper = self.parseString (xsdText) - else: - # a schemaLocation attribute is expected in the root tag of the XML input file - xsdFile = self._retrieveReferencedXsdFile (inputTreeWrapper) - xsdTreeWrapper = self.parse (xsdFile, inputTreeWrapper.getRootNode().getAbsUrl()) - - return self._validateXmlInput ("input text", xsdFile, inputTreeWrapper, xsdTreeWrapper, validateSchema) - - - ######################################## - # validate XML schema separately - # - def validateXmlSchema (self, xsdFile, xsdTreeWrapper): - # parse minixsv internal schema - rulesTreeWrapper = self.parse(os.path.join (_OWNDIR, "xsStructs.xsd")) - - self._verbosePrint ("Validating %s..." %(xsdFile)) - xsvGivenXsdFile = XsValSchema (self.xmlIf, self.errorHandler) - xsvGivenXsdFile.validate(xsdTreeWrapper, rulesTreeWrapper) - self.errorHandler.flushOutput() - return xsdTreeWrapper - - - ######################################## - # validate XML input tree and xsd tree if requested - # - def _validateXmlInput (self, xmlInputFile, xsdFile, inputTreeWrapper, xsdTreeWrapper, validateSchema=0): - # validate XML schema file if requested - if validateSchema: - self.validateXmlSchema (xsdFile, xsdTreeWrapper) - - try: - xsdTreeWrapper.insertSubtree (xsdTreeWrapper.getRootNode().getFirstChild(), os.path.join (_OWNDIR, "datatypes2.xsd"), None) - except AssertionError, errstr: - self.errorHandler.raiseError (errstr) - - self._verbosePrint ("Validating %s..." %(xmlInputFile)) - xsvInputFile = XsValBase (self.xmlIf, self.errorHandler) - xsvInputFile.validate(inputTreeWrapper, xsdTreeWrapper) - self.errorHandler.flushOutput() - return inputTreeWrapper - - - ######################################## - # retrieve XML schema location from XML input tree - # - def _retrieveReferencedXsdFile (self, inputTreeWrapper): - # a schemaLocation attribute is expected in the root tag of the XML input file - for attributeName, attributeValue in inputTreeWrapper.getRootNode().getAttributeDict().items(): - if self.xmlIf.extractLocalName(attributeName) in ("noNamespaceSchemaLocation", "schemaLocation"): - xsdFile = attributeValue - return xsdFile - else: - self.errorHandler.raiseError ("No schema file specified!") - - - ######################################## - # print if verbose flag is set - # - def _verbosePrint (self, text): - if self.verbose: - print text - - - - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/readme.txt --- a/minixsv/readme.txt Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -Release Notes for minixsv, Release 0.3 - -minixsv is a XML schema validator written in "pure" Python. - -Currently only a subset of the XML schema standard is supported -(list of limitations/restrictions see below). - -minixsv currently uses minidom or elementtree as XML parser -Other parsers can easily be adapted by implementing an appropriate interface class -Whitespaces inside strings are automatically normalized/collapsed as specified in the XML schema file -Default/Fixed attributes are automatically inserted if not specified in the input file - --------------------------------------------------------------------- - The minixsv XML schema validator is - - Copyright (c) 2004 by Roland Leuthe - - By obtaining, using, and/or copying this software and/or its - associated documentation, you agree that you have read, understood, - and will comply with the following terms and conditions: - - Permission to use, copy, modify, and distribute this software and - its associated documentation for any purpose and without fee is - hereby granted, provided that the above copyright notice appears in - all copies, and that both that copyright notice and this permission - notice appear in supporting documentation, and that the name of - the author not be used in advertising or publicity - pertaining to distribution of the software without specific, written - prior permission. - - THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- - ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR - BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY - DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - OF THIS SOFTWARE. ---------------------------------------------------------------------- - - -Limitations/restrictions of the current release: - -- No support of namespaces -- Only first text node is validated/processed as Element content -- No validation of predefined types decimal, float, double, date/time types, DURATION, anyURI, base64Binary -- Only partial validation for language, QName, DTD types -- No validation for facets of not validated predefined types (see above) -- Derivation of complex types from simple types not supported -- Mixed content (child nodes and text nodes) not supported -- No check if no element content exists when xsi:nil = "true" is specified -- No support of attributes "elementFormDefault", "attributeFormDefault", "form" -- "import" element not supported -- no check if derived type and base type match -- no check of attributes "final", "finalDefault" -- "redefine" element not supported -- no support of substitution groups -- no support of abstract elements and types -- uniqueness of identity constraints (unique/key/keyref) is only checked on string base - (in case of element content only the first text node is evaluated) -- "processContents" attribute not supported - -Note: This constraint list may not be complete!! - - ---------------------------------------------------------------------- - -Contents -======== - -readme.txt -__init__.py -pyxsval.py -xsvalSchema.py -xsvalBase.py -xsvalSimpleTypes.py -xsvalErrorHandler.py -xmlifbase.py -minidomif.py -elemtreeif.py -xsStructs.xsd -datatypes.xsd -datatypes2.xsd - ---------------------------------------------------------------------- - -HISTORY: -======= - -Changes to Release 0.2 -====================== - -- API re-structured -- XML text processing added -- several bugs fixed -- internal re-structuring - - -Changes to Release 0.1 -====================== - -- Error/warning outputs contain now also filename and linenumber -- Basic URI support for include directive added -- XML interface classes completely re-designed -- several bugs fixed - - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/xmlifbase.py --- a/minixsv/xmlifbase.py Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,465 +0,0 @@ -# -# minixsv, Release 0.3 -# file: xmlifbase.py -# -# abstract XML interface class -# -# history: -# 2004-09-09 rl created -# 2004-09-22 rl XML interface classes completely re-designed -# 2004-09-23 rl added filename and line number support -# 2004-09-29 rl URL processing added -# 2004-10-01 rl URL processing improved -# 2004-10-03 rl xPath processing moved from pyxsval.py -# 2004-10-12 rl XML text processing added -# -# Copyright (c) 2004 by Roland Leuthe. All rights reserved. -# -# -------------------------------------------------------------------- -# The minixsv XML schema validator is -# -# Copyright (c) 2004 by Roland Leuthe -# -# By obtaining, using, and/or copying this software and/or its -# associated documentation, you agree that you have read, understood, -# and will comply with the following terms and conditions: -# -# Permission to use, copy, modify, and distribute this software and -# its associated documentation for any purpose and without fee is -# hereby granted, provided that the above copyright notice appears in -# all copies, and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of -# the author not be used in advertising or publicity -# pertaining to distribution of the software without specific, written -# prior permission. -# -# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD -# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- -# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -# OF THIS SOFTWARE. -# -------------------------------------------------------------------- - - -import string -import os -import re -import urllib -import urlparse - - -_reSplitUrlApplication = re.compile (r"(file|http|ftp|gopher):(.+)") # "file:///d:\test.xml" => "file" + "///d:\test.xml" - - -######################################## -# define XML interface base class -# All not implemented methods have to be overloaded by the derived class!! -# - -class XmlInterfaceBase: - - def __init__(self, verbose): - self.verbose = verbose - pass - - ########################################################## - # calls the parser for 'file' - # returns the respective XML tree for the parsed XML file - # 'file' may be a file path or an URI - - def parse (self, file, baseUrl): - raise NotImplementedError - - - ########################################################## - # calls the parser for 'text' - # returns the respective XML tree for the parsed XML text string - - def parseString (self, text): - raise NotImplementedError - - - ########################################################## - # calls the parser for 'file' and processes all include directives - # returns the respective XML tree wrapper for the parsed XML file - - def extParse (self, file, baseUrl): - treeWrapper = self.parse (file, baseUrl) - return self._expandIncludes (treeWrapper) - - def _expandIncludes (self, treeWrapper): - rootNodeWrapper = treeWrapper.getRootNode() - nsAlias = self.extractNamespaceAlias(rootNodeWrapper.getTagName()) - - for includeNodeWrapper in rootNodeWrapper.getChildrenNS(nsAlias, "include"): - includeUrl = includeNodeWrapper.getAttribute("schemaLocation") - if self.verbose: - print "including %s..." %(includeUrl) - treeWrapper.insertSubtree (includeNodeWrapper, includeUrl, rootNodeWrapper.getAbsUrl()) - rootNodeWrapper.removeChild (includeNodeWrapper) - return treeWrapper - - ########################################################## - # calls the parser for 'file' and processes all include directives - # returns the respective XML tree wrapper for the parsed XML file - - def extParseString (self, text): - treeWrapper = self.parseString (text) - return self._expandIncludes (treeWrapper) - - - ########################################################## - # returns namespace part of given 'ncName' - - def extractNamespaceAlias (self, ncName): - namespaceAlias, localName = self._splitNamespaceLocalName (ncName) - return namespaceAlias - - - ########################################################## - # returns local tag name of given 'ncName' - - def extractLocalName (self, ncName): - namespaceAlias, localName = self._splitNamespaceLocalName (ncName) - return localName - - - ########################################################## - # add namespace alias to localName - - def addNamespaceAlias (self, namespaceAlias, localName): - if namespaceAlias != "": - return namespaceAlias + localName - else: - return localName - - - ############################################################### - # PRIVATE methods - ############################################################### - - ########################################################## - # convert input parameter 'file' into a valid URL - - def _convertToUrl (self, file): - matchObject = _reSplitUrlApplication.match(file) - if matchObject: - # given file is an absolute URL - if matchObject.group(1) == 'file': - path = re.sub(':', '|', matchObject.group(2)) # replace ':' by '|' in the path string - url = "file:" + path - else: - url = file - elif not os.path.isabs(file): - # given file is a relative URL - url = file - else: - # given file is not a valid URL => treated as local filename - url = "file:" + urllib.pathname2url (file) - - return url - - def _convertToAbsUrl (self, url, baseUrl): - application = urlparse.urlsplit(url)[0] - if application == '': - if baseUrl != "": - url = urlparse.urljoin (baseUrl, url) - else: - url = "file:" + urllib.pathname2url (os.path.join(os.getcwd(), url)) - return url - - ########################################################## - # split 'ncName' into namespace and local name - - def _splitNamespaceLocalName (self, ncName): - namespaceAlias = None - - namespaceEndIndex = string.find (ncName, '}') - if namespaceEndIndex != -1: - namespaceAlias = ncName[:namespaceEndIndex+1] - localName = ncName[namespaceEndIndex+1:] - else: - namespaceEndIndex = string.find (ncName, ':') - if namespaceEndIndex != -1: - namespaceAlias = ncName[:namespaceEndIndex+1] - localName = ncName[namespaceEndIndex+1:] - else: - namespaceAlias = "" - localName = ncName - return namespaceAlias, localName - - - -######################################## -# define tree wrapper base class -# All not implemented methods have to be overloaded by the derived class!! -# - -class TreeWrapperBase: - - def __init__(self, xmlIf, tree): - self.xmlIf = xmlIf - self.tree = tree - - ########################################################## - # includes the given XML/XSD file 'file' into the XML tree 'tree' - # before 'nextSibling' ('nextSibling' is not removed!) - # returns the extended XML tree (containing included XML/XSD file) - # - # Note: Root tag of 'tree' and 'file' must match! - - def insertSubtree (self, nextSibling, file, baseUrl): - raise NotImplementedError - - - ########################################################## - # returns root node of given XML tree 'tree' - - def getRootNode (self): - raise NotImplementedError - - - ########################################################## - # returns 'tree' of given XML tree - - def getTree (self): - return self.tree - -######################################## -# define node wrapper base class -# All not implemented methods have to be overloaded by the derived class!! -# - -class ElementWrapperBase: - - def __init__(self, xmlIf, treeWrapper, element): - self.xmlIf = xmlIf - self.treeWrapper = treeWrapper - self.element = element - - ########################################################## - # returns tag name of given XML node 'node' - - def getTagName (self): - raise NotImplementedError - - - ########################################################## - # returns child element nodes (list) of given XML node 'node' - # 'filterTag' is optional, 'filterTag' = '*' must be supported - - def getChildren (self, filterTag=None): - raise NotImplementedError - - - ########################################################## - # returns all descendants of node whose tag match 'tagName' - # 'filterTag' is optional, 'filterTag' = '*' must be supported - - def getElementsByTagName (self, filterTag=None): - raise NotImplementedError - - - ########################################################## - # remove given child node from children of current node - - def removeChild (self, childNodeWrapper): - raise NotImplementedError - - - ########################################################## - # returns dictionary with all attributes of this node - - def getAttributeDict (self): - raise NotImplementedError - - - ########################################################## - # returns attribute value of given attributeName - # or None if there is no suitable attribute - - def getAttribute (self, attributeName): - raise NotImplementedError - - ########################################################## - # returns 1 if attribute 'attributeName' exists - # 0 if not - - def hasAttribute (self, attributeName): - raise NotImplementedError - - - ########################################################## - # sets value of attribute 'attributeName' to 'attributeValue' - # if the attribute does not yet exist, it will be created - - def setAttribute (self, attributeName, attributeValue): - raise NotImplementedError - - - ########################################################## - # returns element value of this node - - def getElementValue (self): - raise NotImplementedError - - - ########################################################## - # sets element value of this node to 'value' - - def setElementValue (self, value): - raise NotImplementedError - - - ########################################################## - # returns local tag name of given XML node 'node' (without namespace) - - def getLocalName (self): - return self.xmlIf.extractLocalName (self.getTagName()) - - - ########################################################## - # returns namespace of tag name of given XML node 'node' - - def getNamespaceURI (self): - return extractNamespaceAlias (self.getTagName()) - - - ########################################################## - # returns child element nodes (list) of given XML node 'node' - # 'filterTag' (localTagName) is optional, 'filterTag' = '*' must be supported - # 'namespaceAlias' has to contain corresponding namespace - - def getChildrenNS (self, namespaceAlias, filterTag=None): - if not filterTag in (None, '*'): - filterTag = self.xmlIf.addNamespaceAlias(namespaceAlias, filterTag) - return self.getChildren(filterTag) - - - ########################################################## - # returns first child element of given XML node 'node' - # or None if there is no suitable child element - # 'filterTag' is optional, 'filterTag' = '*' must be supported - - def getFirstChild (self, filterTag=None): - children = self.getChildren(filterTag) - if children != []: - return children[0] - else: - return None - - - ########################################################## - # returns first child element of given XML node 'node' - # or None if there is no suitable child element - # 'filterTag' (localTagName) is optional, 'filterTag' = '*' must be supported - # 'namespaceAlias' has to contain corresponding namespace - - def getFirstChildNS (self, namespaceAlias, filterTag=None): - if not filterTag in (None, '*'): - filterTag = self.xmlIf.addNamespaceAlias(namespaceAlias, filterTag) - return self.getFirstChild(filterTag) - - - ########################################################## - # returns all descendants of node whose tag match 'localName' of the given namespace - # 'filterTag' (localTagName) is optional, 'filterTag' = '*' must be supported - # 'namespaceAlias' has to contain corresponding namespace - - def getElementsByTagNameNS (self, namespaceAlias, filterTag=None): - if not filterTag in (None, '*'): - filterTag = self.xmlIf.addNamespaceAlias(namespaceAlias, filterTag) - return self.getElementsByTagName (filterTag) - - - ########################################################## - # returns attribute if it exists or default value if not - - def getAttributeOrDefault (self, attributeName, default): - if self.hasAttribute (attributeName): - return self.getAttribute (attributeName) - else: - return default - - ########################################################## - # returns the current start line number of the element node in the XML file - - def getStartLineNumber (self): - return self.element.startLineNumber - - - ########################################################## - # returns the current end line number of the element node in the XML file - - def getEndLineNumber (self): - return self.element.endLineNumber - - - ########################################################## - # returns the URL of the XML file the node belongs to - - def getUrl (self): - return self.element.url - - def getAbsUrl (self): - return self.element.absUrl - - - ########################################################## - # returns the file path of the XML file the node belongs to - - def getFilePath (self): - return self.element.filePath - - - ######################################## - # retrieve node list or attribute list for specified XPath - - def getXPathList (self, xPath, defaultNamespace): - selectedNodeList = [] - selectedAttributeList = [] - xPathList = string.split (xPath, "|") - for xRelPath in xPathList: - descendantOrSelf = 0 - if xRelPath[:3] == ".//": - descendantOrSelf = 1 - xRelPath = xRelPath[3:] - # no namespaces supported! - xPathLocalStepList = map(lambda xPath: self.xmlIf.extractLocalName(xPath), string.split (xRelPath, "/")) - childList = [self,] - isAttributeList = 0 - for localStep in xPathLocalStepList: - stepChildList = [] - if localStep == "": - raise IOError ("Invalid xPath '%s'!" %(xRelPath)) - elif localStep == ".": - continue - elif localStep[0] == '@': - for childNode in childList: - attrName = localStep[1:] - if attrName == '*': - stepChildList.extend(childNode.getAttributeDict().values()) - elif childNode.hasAttribute(attrName): - stepChildList.append (childNode.getAttribute(attrName)) - childList = stepChildList - isAttributeList = 1 - else: - if descendantOrSelf: - descendantOrSelf = 0 - stepChildList = self.getElementsByTagNameNS(defaultNamespace, localStep) - else: - for childNode in childList: - stepChildList.extend (childNode.getChildrenNS(defaultNamespace, localStep)) - childList = stepChildList - - if isAttributeList: - selectedAttributeList.extend (childList) - else: - selectedNodeList.extend (childList) - return selectedNodeList, selectedAttributeList - - - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/xsStructs.xsd --- a/minixsv/xsStructs.xsd Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1217 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - -]> - - - - - The schema corresponding to this document is normative, - with respect to the syntactic constraints it expresses in the - XML Schema language. The documentation (within <documentation> elements) - below, is not normative, but rather highlights important aspects of - the W3C Recommendation of which this is a part - - - - - The simpleType element and all of its members are defined - in datatypes.xsd - - - - - - - - Get access to the xml: attribute groups for xml:lang - as declared on 'schema' and 'documentation' below - - - - - - - - This type is extended by almost all schema types - to allow attributes from other namespaces to be - added to user schemas. - - - - - - - - - - - - - This type is extended by all types which allow annotation - other than <schema> itself - - - - - - - - - - - - - - - - This group is for the - elements which occur freely at the top level of schemas. - All of their types are based on the "annotated" type by extension. - - - - - - - - - - - - - - This group is for the - elements which can self-redefine (see <redefine> below). - - - - - - - - - - - - - - A utility type, not for public use - - - - - - - - - - - - A utility type, not for public use - - - - - - - - - - - - A utility type, not for public use - - - #all or (possibly empty) subset of {extension, restriction} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - for maxOccurs - - - - - - - - - - - - for all particles - - - - - - - for element, group and attributeGroup, - which both define and reference - - - - - - - - 'complexType' uses this - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This branch is short for - <complexContent> - <restriction base="xs:anyType"> - ... - </restriction> - </complexContent> - - - - - - - - - - - - - - - - Will be restricted to required or forbidden - - - - - - - Not allowed if simpleContent child is chosen. - May be overriden by setting on complexContent child. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overrides any setting on complexType parent. - - - - - - - - - - - - - - - - - - - - - - - - - - No typeDefParticle group reference - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A utility type, not for public use - - #all or (possibly empty) subset of {substitution, extension, - restriction} - - - - - - - - - - - - - - - - - - - - - - - - - The element element can be used either - at the top level to define an element-type binding globally, - or within a content model to either reference a globally-defined - element or type or declare an element-type binding locally. - The ref form is not allowed at the top level. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - group type for explicit groups, named top-level groups and - group references - - - - - - - - - - - - - - - - - - - - - - - - - - - - Should derive this from realGroup, but too complicated - for now - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - group type for the three kinds of group - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - restricted max/min - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Only elements allowed inside - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - simple type for the value of the 'namespace' attr of - 'any' and 'anyAttribute' - - - - Value is - ##any - - any non-conflicting WFXML/attribute at all - - ##other - - any non-conflicting WFXML/attribute from - namespace other than targetNS - - ##local - - any unqualified non-conflicting WFXML/attribute - - one or - - any non-conflicting WFXML/attribute from - more URI the listed namespaces - references - (space separated) - - ##targetNamespace or ##local may appear in the above list, to - refer to the targetNamespace of the enclosing - schema or an absent targetNamespace respectively - - - - - - A utility type, not for public use - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A subset of XPath expressions for use -in selectors - A utility type, not for public -use - - - - The following pattern is intended to allow XPath - expressions per the following EBNF: - Selector ::= Path ( '|' Path )* - Path ::= ('.//')? Step ( '/' Step )* - Step ::= '.' | NameTest - NameTest ::= QName | '*' | NCName ':' '*' - child:: is also allowed - - - - - - - - - - - - - - - - - - - - - - - A subset of XPath expressions for use -in fields - A utility type, not for public -use - - - - The following pattern is intended to allow XPath - expressions per the same EBNF as for selector, - with the following change: - Path ::= ('.//')? ( Step '/' )* ( Step | '@' NameTest ) - - - - - - - - - - - - - - - - - - - - - - - - - - - The three kinds of identity constraints, all with - type of or derived from 'keybase'. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A utility type, not for public use - - A public identifier, per ISO 8879 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - notations for use within XML Schema schemas - - - - - - - - - Not the real urType, but as close an approximation as we can - get in the XML representation - - - - - - - - - - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/xsvalBase.py --- a/minixsv/xsvalBase.py Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,602 +0,0 @@ -# -# minixsv, Release 0.3 -# file: xsvalBase.py -# -# XML schema validator base class -# -# history: -# 2004-10-07 rl created -# -# Copyright (c) 2004 by Roland Leuthe. All rights reserved. -# -# -------------------------------------------------------------------- -# The minixsv XML schema validator is -# -# Copyright (c) 2004 by Roland Leuthe -# -# By obtaining, using, and/or copying this software and/or its -# associated documentation, you agree that you have read, understood, -# and will comply with the following terms and conditions: -# -# Permission to use, copy, modify, and distribute this software and -# its associated documentation for any purpose and without fee is -# hereby granted, provided that the above copyright notice appears in -# all copies, and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of -# the author not be used in advertising or publicity -# pertaining to distribution of the software without specific, written -# prior permission. -# -# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD -# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- -# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -# OF THIS SOFTWARE. -# -------------------------------------------------------------------- - -from xsvalErrorHandler import * -import xsvalSimpleTypes - -########################################################### -# Validator class for validating one input file against one XML schema file - -class XsValBase: - - def __init__(self, xmlIf, errorHandler): - self.xmlIf = xmlIf - self.errorHandler = errorHandler - - self._raiseError = self.errorHandler.raiseError - self._addError = self.errorHandler.addError - self._addWarning = self.errorHandler.addWarning - - self.checkKeyrefList = [] - - - ######################################## - # validate inputTree against xsdTree - # - def validate (self, inputTree, xsdTree): - self.inputTree = inputTree - self.xsdTree = xsdTree - - self.xsdRoot = self.xsdTree.getRootNode() - self.xsdNSAlias = self.xmlIf.extractNamespaceAlias(self.xsdRoot.getTagName()) - self.inputRoot = self.inputTree.getRootNode() - self.inputNSAlias = self.xmlIf.extractNamespaceAlias(self.inputRoot.getTagName()) - - self.simpleTypeVal = xsvalSimpleTypes.XsSimpleTypeVal(self) - - self._setupLookupTables() - - inputRootTagName = self.inputRoot.getTagName() - inputRootLocalName = self.inputRoot.getLocalName() - if self.xsdElementDict.has_key(inputRootLocalName): - # start recursive schema validation - try: - self._checkElementTag (self.xsdElementDict[inputRootLocalName], inputRootTagName, (self.inputRoot,), 0) - except TagException, errInst: - self._addError (errInst.errstr, errInst.node, errInst.endTag) - - # validate keyrefs - for inputElement, keyrefNode in self.checkKeyrefList: - self._checkKeyRefConstraint (keyrefNode, inputElement) - else: - self._raiseError ("Used root tag %s not found in schema file!" %(inputRootTagName), self.inputRoot) - - - ######################################## - # setup lookup dictionaries used during validation - # - def _setupLookupTables (self): - # retrieve all elements - self.xsdElementDict = {} - for xsdTypeNode in self.xsdRoot.getChildrenNS(self.xsdNSAlias, "element"): - self.xsdElementDict[xsdTypeNode.getAttribute("name")] = xsdTypeNode - - # retrieve all type definitions (complex and simple types) - self.xsdTypeDict = {} - for xsdTypeNode in self.xsdRoot.getChildrenNS(self.xsdNSAlias, "complexType"): - self.xsdTypeDict[xsdTypeNode.getAttribute("name")] = xsdTypeNode - - for xsdTypeNode in self.xsdRoot.getChildrenNS(self.xsdNSAlias, "simpleType"): - self.xsdTypeDict[xsdTypeNode.getAttribute("name")] = xsdTypeNode - - # retrieve all group definitions - self.xsdGroupDict = {} - for xsdTypeNode in self.xsdRoot.getChildrenNS(self.xsdNSAlias, "group"): - self.xsdGroupDict[xsdTypeNode.getAttribute("name")] = xsdTypeNode - - # retrieve all attribute group definitions - self.xsdAttributeGroupDict = {} - for xsdTypeNode in self.xsdRoot.getChildrenNS(self.xsdNSAlias, "attributeGroup"): - self.xsdAttributeGroupDict[xsdTypeNode.getAttribute("name")] = xsdTypeNode - - # retrieve all identity constraints - self.xsdIdentityConstrDict = {} - for identConstrTagName in ("unique", "key", "keyref"): - identConstrNodeList = self.xsdRoot.getElementsByTagNameNS (self.xsdNSAlias, identConstrTagName) - for identConstrNode in identConstrNodeList: - identConstrName = identConstrNode.getAttribute("name") - if not self.xsdIdentityConstrDict.has_key(identConstrName): - self.xsdIdentityConstrDict[identConstrName] = {"Node": identConstrNode, "ValueDict":{}} - else: - self._raiseError ("Duplicate identity constraint name '%s' found in schema definition!" %(identConstrName), identConstrNode) - - - ######################################## - # validate inputElement against complexType node - # - def _checkComplexTypeTag (self, xsdParentElementNode, xsdElement, inputElement, inputElementChildIndex, usedAsBaseType=None): - baseTypeAttributes = {"__SPECIAL_ATTRS__":{}} - if xsdParentElementNode.getAttribute ("nillable") == "true": - baseTypeAttributes["__SPECIAL_ATTRS__"]["nil"] = "xsd:boolean" - - complexContentElement = xsdElement.getFirstChildNS(self.xsdNSAlias, "complexContent") - if complexContentElement != None: - inputElementChildIndex, baseTypeAttributes = self._checkComplexContentTag (xsdParentElementNode, complexContentElement, inputElement, inputElementChildIndex, usedAsBaseType, baseTypeAttributes) - else: - inputElementChildIndex, baseTypeAttributes = self._checkComplexTypeContent (xsdElement, inputElement, inputElementChildIndex, usedAsBaseType, baseTypeAttributes) - return inputElementChildIndex, baseTypeAttributes - - def _checkComplexContentTag (self, xsdParentElementNode, xsdElement, inputElement, inputElementChildIndex, usedAsBaseType, baseTypeAttributes): - extensionElement = xsdElement.getFirstChildNS(self.xsdNSAlias, "extension") - if extensionElement != None: - inputElementChildIndex, baseTypeAttributes = self._checkExtensionComplexContent (xsdParentElementNode, extensionElement, inputElement, inputElementChildIndex, usedAsBaseType, baseTypeAttributes) - else: - restrictionElement = xsdElement.getFirstChildNS(self.xsdNSAlias, "restriction") - if restrictionElement != None: - inputElementChildIndex, baseTypeAttributes = self._checkRestrictionComplexContent (xsdParentElementNode, restrictionElement, inputElement, inputElementChildIndex, usedAsBaseType, baseTypeAttributes) - return inputElementChildIndex, baseTypeAttributes - - def _checkExtensionComplexContent (self, xsdParentElementNode, xsdElement, inputElement, inputElementChildIndex, usedAsBaseType, baseTypeAttributes): - baseType = self.xmlIf.extractLocalName(xsdElement.getAttribute("base")) - inputElementChildIndex, baseTypeAttributes = self._checkComplexTypeTag (xsdParentElementNode, self.xsdTypeDict[baseType], inputElement, inputElementChildIndex, "extension") - - inputElementChildIndex, baseTypeAttributes = self._checkComplexTypeContent (xsdElement, inputElement, inputElementChildIndex, usedAsBaseType, baseTypeAttributes) - return inputElementChildIndex, baseTypeAttributes - - def _checkRestrictionComplexContent (self, xsdParentElementNode, xsdElement, inputElement, inputElementChildIndex, usedAsBaseType, baseTypeAttributes): - # first check against base type (retrieve only the base type attributes) - baseType = self.xmlIf.extractLocalName(xsdElement.getAttribute("base")) - inputElementChildIndex, baseTypeAttributes = self._checkComplexTypeTag (xsdParentElementNode, self.xsdTypeDict[baseType], inputElement, inputElementChildIndex, "restriction") - - # then check input against derived complex type - inputElementChildIndex, baseTypeAttributes = self._checkComplexTypeContent (xsdElement, inputElement, inputElementChildIndex, usedAsBaseType, baseTypeAttributes) - return inputElementChildIndex, baseTypeAttributes - - def _checkComplexTypeContent (self, xsdElement, inputElement, inputElementChildIndex, usedAsBaseType, baseTypeAttributes): - inputTagName = inputElement.getTagName() - childTags = inputElement.getChildren() - if usedAsBaseType in (None, "extension"): - validChildTags = xsdElement.getChildren() - for validChildTag in validChildTags: - if validChildTag.getLocalName() not in ("attribute", "attributeGroup", "anyAttribute"): - inputElementChildIndex = self._checkParticle (validChildTag, inputElement, childTags, inputElementChildIndex) - - if usedAsBaseType == None and inputElementChildIndex < len (childTags): - self._addError ("Unexpected child tag '%s' in tag '%s' found!" %(childTags[inputElementChildIndex].getTagName(), inputTagName), childTags[inputElementChildIndex]) - - if usedAsBaseType in (None,): - self._checkAttributeTags (xsdElement, inputElement, baseTypeAttributes) - - if usedAsBaseType in ("restriction", "extension"): - validAttributes = xsdElement.getChildrenNS(self.xsdNSAlias, "attribute") - for validAttrGroup in xsdElement.getChildrenNS(self.xsdNSAlias, "attributeGroup"): - attributeGroupRef = self.xmlIf.extractLocalName(validAttrGroup.getAttribute("ref")) - validAttributes.extend (self.xsdAttributeGroupDict[attributeGroupRef].getChildrenNS(self.xsdNSAlias, "attribute")) - for validAttribute in validAttributes: - baseTypeAttributes[validAttribute.getAttribute("name")] = validAttribute - return inputElementChildIndex, baseTypeAttributes - - - ######################################## - # validate inputNodeList against xsdNode - # - def _checkList (self, elementMethod, xsdNode, inputParentNode, inputNodeList, currIndex): - if not xsdNode.hasAttribute("minOccurs"): - xsdNode.setAttribute("minOccurs", "1") # default - if not xsdNode.hasAttribute("maxOccurs"): - xsdNode.setAttribute("maxOccurs", "1") # default - - minOccurs = string.atoi(xsdNode.getAttribute("minOccurs")) - maxOccurs = -1 - if xsdNode.getAttribute("maxOccurs") != "unbounded": - maxOccurs = string.atoi(xsdNode.getAttribute("maxOccurs")) - occurs = 0 - while maxOccurs == -1 or occurs < maxOccurs: - try: - newIndex = elementMethod (xsdNode, inputParentNode, inputNodeList, currIndex) - occurs += 1 - if newIndex > currIndex: - currIndex = newIndex - else: - break # no suitable element found - except TagException, errInst: - break - - if occurs == 0 and minOccurs > 0: - raise errInst - elif occurs < minOccurs: - expInputTagName = xsdNode.getAttribute("name") - if expInputTagName == None: - expInputTagName = self.xmlIf.extractLocalName(xsdNode.getAttribute("ref")) - - errInst.errstr = "Minimum number (%d) of child tags '%s' in tag '%s' not available (only %d)!" %(minOccurs, expInputTagName, inputParentNode.getTagName(), occurs) - raise errInst - - return currIndex - - ######################################## - # validate inputNode against element node - # - def _checkElementTag (self, xsdNode, inputParentNode, inputNodeList, currIndex): - if xsdNode.hasAttribute("ref"): - refAttr = self.xmlIf.extractLocalName(xsdNode.getAttribute("ref")) - currIndex = self._checkElementTag (self.xsdElementDict[refAttr], inputParentNode, inputNodeList, currIndex) - - else: - nameAttr = xsdNode.getAttribute ("name") - if currIndex >= len (inputNodeList): - raise TagException ("Missing child tag '%s' in tag '%s'!" %(nameAttr, inputParentNode.getTagName()), inputParentNode, 1) - - inputNode = inputNodeList[currIndex] - if nameAttr != inputNode.getLocalName(): - raise TagException ("Missing child tag '%s' in tag '%s'!" %(nameAttr, inputParentNode.getTagName()), inputNode, 0) - - simpleType = None - complexTypeNode = xsdNode.getFirstChildNS (self.xsdNSAlias, "complexType") - simpleTypeNode = xsdNode.getFirstChildNS (self.xsdNSAlias, "simpleType") - if xsdNode.hasAttribute("type"): - typeAttr = xsdNode.getAttribute ("type") - localTypeAttr = self.xmlIf.extractLocalName(typeAttr) - if self.xsdTypeDict.has_key (localTypeAttr) and self.xsdTypeDict[localTypeAttr].getLocalName() == "complexType": - complexTypeNode = self.xsdTypeDict[localTypeAttr] - else: - simpleType = typeAttr - - if complexTypeNode != None: - try: - self._checkComplexTypeTag (xsdNode, complexTypeNode, inputNode, 0) - except TagException, errInst: - self._addError (errInst.errstr, errInst.node, errInst.endTag) - else: - try: - simpleTypeReturnDict = {} - if simpleTypeNode != None: - self.simpleTypeVal.checkSimpleTypeDef (simpleTypeNode, inputNode.getTagName(), inputNode.getElementValue(), simpleTypeReturnDict) - elif simpleType != None: - self.simpleTypeVal.checkSimpleType (inputNode.getTagName(), simpleType, inputNode.getElementValue(), simpleTypeReturnDict) - # TODO: What to check if np type is specified for the element? - - if simpleTypeReturnDict.has_key("adaptedAttrValue"): - inputNode.setElementValue(simpleTypeReturnDict["adaptedAttrValue"]) - - except xsvalSimpleTypes.SimpleTypeError, errstr: - self._addError (str(errstr), inputNode) - - currIndex += 1 - - # check unique attributes and keys - childUniqueDefList = xsdNode.getChildrenNS (self.xsdNSAlias, "unique") - for childUniqueDef in childUniqueDefList: - self._checkIdentityConstraint (childUniqueDef, inputNode, "unique") - - childKeyDefList = xsdNode.getChildrenNS (self.xsdNSAlias, "key") - for childKeyDef in childKeyDefList: - self._checkIdentityConstraint (childKeyDef, inputNode, "key") - - childKeyrefDefList = xsdNode.getChildrenNS (self.xsdNSAlias, "keyref") - for childKeyrefDef in childKeyrefDefList: - self.checkKeyrefList.append ((inputNode, childKeyrefDef)) - - return currIndex - - - ######################################## - # validate inputNode against sequence node - # - def _checkSequenceTag (self, xsdNode, inputParentNode, inputNodeList, currIndex): - for xsdChildNode in xsdNode.getChildren(): - currIndex = self._checkParticle (xsdChildNode, inputParentNode, inputNodeList, currIndex) - return currIndex - - ######################################## - # validate inputNode against choice node - # - def _checkChoiceTag (self, xsdNode, inputParentNode, inputNodeList, currIndex): - for xsdChildNode in xsdNode.getChildren(): - try: - currIndex = self._checkParticle (xsdChildNode, inputParentNode, inputNodeList, currIndex) - break - except TagException, errInst: - pass - else: - if currIndex < len(inputNodeList): - currNode = inputNodeList[currIndex] - endTag = 0 - else: - currNode = inputParentNode - endTag = 1 - raise TagException ("No suitable child tag for choice found!", currNode, endTag) - - return currIndex - - ######################################## - # validate inputNode against group node - # - def _checkGroupTag (self, xsdNode, inputParentNode, inputNodeList, currIndex): - if xsdNode.hasAttribute("ref"): - refAttr = self.xmlIf.extractLocalName(xsdNode.getAttribute("ref")) - currIndex = self._checkGroupTag (self.xsdGroupDict[refAttr], inputParentNode, inputNodeList, currIndex) - else: - for xsdChildNode in xsdNode.getChildren(): - currIndex = self._checkParticle (xsdChildNode, inputParentNode, inputNodeList, currIndex) - return currIndex - - ######################################## - # validate inputNode against all node - # - def _checkAllTag (self, xsdNode, inputParentNode, inputNodeList, currIndex): - oldIndex = currIndex - xsdChildDict = {} - for xsdChildNode in xsdNode.getChildren(): - xsdChildDict[xsdChildNode] = 0 - while currIndex < len(inputNodeList): - currNode = inputNodeList[currIndex] - for xsdChildNode in xsdChildDict.keys(): - try: - newIndex = self._checkParticle (xsdChildNode, inputParentNode, inputNodeList, currIndex) - except TagException, errInst: - continue - - if xsdChildDict[xsdChildNode] == 0: - xsdChildDict[xsdChildNode] = 1 - currIndex = newIndex - break - else: - raise TagException ("Ambiguous child tag '%s' found in all-group!" %(currNode.getTagName()), currNode) - else: - raise TagException ("Unexpected child tag '%s' for all-group found!" %(currNode.getTagName()), currNode) - - for xsdChildNode, occurs in xsdChildDict.items(): - if xsdChildNode.getAttribute("minOccurs") != "0" and occurs == 0: - raise TagException ("Child tag '%s' missing in all-group (%s)" %(xsdChildNode.getAttribute("name"), inputParentNode.getTagName()), inputNodeList[oldIndex]) - - return currIndex - - - ######################################## - # validate inputNode against any node - # - def _checkAnyTag (self, xsdNode, inputParentNode, inputNodeList, currIndex): - processContents = xsdNode.getAttribute("processContents") - if processContents == "skip": - pass - elif processContents == "lax": - # TODO: Was muss hier gecheckt werden? - pass - elif processContents == "strict": - # TODO: Was muss hier gecheckt werden? - pass - - if currIndex < len(inputNodeList): - currIndex = currIndex + 1 - - return currIndex - - ######################################## - # validate inputNode against particle - # - def _checkParticle (self, xsdNode, inputParentNode, inputNodeList, currIndex): - xsdTagName = xsdNode.getTagName() - if xsdTagName == self.xsdNSAlias + "element": - currIndex = self._checkList (self._checkElementTag, xsdNode, inputParentNode, inputNodeList, currIndex) - elif xsdTagName == self.xsdNSAlias + "choice": - currIndex = self._checkList (self._checkChoiceTag, xsdNode, inputParentNode, inputNodeList, currIndex) - elif xsdTagName == self.xsdNSAlias + "sequence": - currIndex = self._checkList (self._checkSequenceTag, xsdNode, inputParentNode, inputNodeList, currIndex) - elif xsdTagName == self.xsdNSAlias + "group": - currIndex = self._checkList (self._checkGroupTag, xsdNode, inputParentNode, inputNodeList, currIndex) - elif xsdTagName == self.xsdNSAlias + "all": - currIndex = self._checkList (self._checkAllTag, xsdNode, inputParentNode, inputNodeList, currIndex) - elif xsdTagName == self.xsdNSAlias + "any": - currIndex = self._checkList (self._checkAnyTag, xsdNode, inputParentNode, inputNodeList, currIndex) - elif xsdTagName == self.xsdNSAlias + "annotation": - pass # nothing to check - else: - self._addError ("Internal error: Invalid tag %s found!" %(xsdTagName)) - return currIndex - - - ######################################## - # validate attributes of inputNode against complexType node - # - def _checkAttributeTags (self, xsdNode, inputNode, validAttrDict): - validAttributes = xsdNode.getChildrenNS(self.xsdNSAlias, "attribute") - for validAttrGroup in xsdNode.getChildrenNS(self.xsdNSAlias, "attributeGroup"): - attributeGroupRef = self.xmlIf.extractLocalName(validAttrGroup.getAttribute("ref")) - validAttributes.extend (self.xsdAttributeGroupDict[attributeGroupRef].getChildrenNS(self.xsdNSAlias, "attribute")) - for validAttribute in validAttributes: - if validAttribute.hasAttribute("name"): - keyAttr = validAttribute.getAttribute("name") - else: - keyAttr = self.xmlIf.extractLocalName(validAttribute.getAttribute("ref")) - validAttrDict[keyAttr] = validAttribute - - inputAttrDict = {} - for iAttrName, iAttrValue in inputNode.getAttributeDict().items(): - if self.xmlIf.extractNamespaceAlias (iAttrName) != "xmlns:" and iAttrName != "xmlns": - inputAttrDict[self.xmlIf.extractLocalName(iAttrName)] = iAttrValue - - for attrKey, validAttribute in validAttrDict.items(): - # handle special attributes, e.g. xsi:nil - if attrKey == "__SPECIAL_ATTRS__": - for specialAttrName, specialAttrType in validAttribute.items(): - if inputAttrDict.has_key(specialAttrName): - simpleTypeReturnDict = {} - try: - self.simpleTypeVal.checkSimpleType (specialAttrName, specialAttrType, inputAttrDict[specialAttrName], simpleTypeReturnDict) - except xsvalSimpleTypes.SimpleTypeError, errstr: - self._addError (str(errstr), inputNode) - - del inputAttrDict[specialAttrName] - continue - - attrDict = validAttribute.getAttributeDict() - if attrDict.has_key("ref"): - # TODO: What to do here?? - attrRef = self.xmlIf.extractLocalName(attrDict["ref"]) - if inputAttrDict.has_key(attrRef): - del inputAttrDict[attrRef] - else: - attrName = attrDict["name"] - if not attrDict.has_key("use"): - attrDict["use"] = "optional" - - if inputAttrDict.has_key(attrName): - del inputAttrDict[attrName] - else: - if attrDict["use"] == "required": - self._addError ("Attribute '%s' is missing for tag %s!" %(attrName, inputNode.getTagName()), inputNode) - elif attrDict["use"] == "optional": - if attrDict.has_key("default"): - inputNode.setAttribute(attrName, attrDict["default"]) - if attrDict.has_key("fixed"): - if inputNode.getAttribute(attrName) != attrDict["fixed"]: - self._addError ("Attribute '%s' must have fixed value '%s'!" %(attrName, attrDict["fixed"]), inputNode) - - if inputNode.hasAttribute(attrName): - if attrDict["use"] == "prohibited": - self._addError ("Attribute '%s' is prohibited in this context!" %(attrName), inputNode) - else: - attributeValue = inputNode.getAttribute(attrName) - try: - simpleTypeReturnDict = {} - if attrDict.has_key("type"): - self.simpleTypeVal.checkSimpleType (attrName, attrDict["type"], attributeValue, simpleTypeReturnDict) - else: - typedefNode = validAttribute.getFirstChildNS(self.xsdNSAlias, "simpleType") - if typedefNode != None: - self.simpleTypeVal.checkSimpleTypeDef (typedefNode, attrName, attributeValue, simpleTypeReturnDict) - else: - pass # default if no type attribute is specified - - if simpleTypeReturnDict.has_key("adaptedAttrValue"): - inputNode.setAttribute(attrName, simpleTypeReturnDict["adaptedAttrValue"]) - - except xsvalSimpleTypes.SimpleTypeError, errstr: - self._addError (str(errstr), inputNode) - - for inputAttribute in inputAttrDict.keys(): - # TODO: adapt for using namespaces!! - if self.xmlIf.extractLocalName(inputAttribute) in ("noNamespaceSchemaLocation", "schemaLocation"): - del inputAttrDict[inputAttribute] - - for inputAttribute in inputAttrDict.keys(): - if inputAttribute == "nil": - self._addError ("Tag '%s' hasn't been defined as nillable!" %(inputNode.getTagName()), inputNode) - else: - self._addError ("Unexpected attribute '%s' in Tag '%s'!" %(inputAttribute, inputNode.getTagName()), inputNode) - - - ######################################## - # validate unique and key definition - # - def _checkIdentityConstraint (self, identityConstrNode, inputElement, isKey): - identConstrName = identityConstrNode.getAttribute ("name") - selectorXPathNode = identityConstrNode.getFirstChildNS (self.xsdNSAlias, "selector") - selectorNodeList, dummy = self._getXPath (inputElement, selectorXPathNode.getAttribute("xpath"), self.inputNSAlias) - - valueDict = {} - for selectorNode in selectorNodeList: - fieldXPathNodeList = identityConstrNode.getChildrenNS (self.xsdNSAlias, "field") - keyValue = [] - for fieldXPathNode in fieldXPathNodeList: - fieldXPath = fieldXPathNode.getAttribute("xpath") - fieldNodeList, fieldAttributeList = self._getXPath (selectorNode, fieldXPath, self.inputNSAlias, isKey) - if len(fieldNodeList) > 1 or len(fieldAttributeList) > 1: - self._addError ("The field xPath of identity constraint '%s' must evaluate to exactly 0 or 1 node!" %(identConstrName), fieldXPathNode) - return - - # TODO: unique and key check currently only on string base - for fieldNode in fieldNodeList: - keyValue.append (fieldNode.getElementValue ()) - - for attrValue in fieldAttributeList: - keyValue.append (attrValue) - - if keyValue != []: - keyValue = tuple(keyValue) - if not valueDict.has_key (keyValue): - valueDict[keyValue] = 1 - self.xsdIdentityConstrDict[identConstrName]["ValueDict"][keyValue] = 1 - else: - self._addError ("Duplicate identity constraint values '%s' found for identity contraint '%s'!" %(keyValue, identConstrName), selectorNode) - - ######################################## - # validate unique and key definition - # - def _checkKeyRefConstraint (self, keyrefNode, inputElement): - keyRefName = keyrefNode.getAttribute ("name") - keyReference = keyrefNode.getAttribute ("refer") - if not self.xsdIdentityConstrDict.has_key (keyReference): - self._addError ("keyref refers unknown key '%s'!" %(keyReference), keyrefNode) - return - - selectorXPathNode = keyrefNode.getFirstChildNS (self.xsdNSAlias, "selector") - selectorNodeList, dummy = self._getXPath (inputElement, selectorXPathNode.getAttribute("xpath"), self.inputNSAlias) - - for selectorNode in selectorNodeList: - fieldXPathNodeList = keyrefNode.getChildrenNS(self.xsdNSAlias, "field") - keyValue = [] - for fieldXPathNode in fieldXPathNodeList: - fieldXPath = fieldXPathNode.getAttribute("xpath") - fieldNodeList, fieldAttributeList = self._getXPath (selectorNode, fieldXPath, self.inputNSAlias, "keyref") - if len(fieldNodeList) > 1 or len(fieldAttributeList) > 1: - self._addError ("The field xPath of keyref '%s' must evaluate to exactly 0 or 1 node!" %(keyRefName), fieldXPathNode) - return - - # TODO: unique and key check currently only on string base - for fieldNode in fieldNodeList: - keyValue.append(fieldNode.getElementValue()) - - for attrValue in fieldAttributeList: - keyValue.append(attrValue) - - keyValue = tuple(keyValue) - if not self.xsdIdentityConstrDict[keyReference]["ValueDict"].has_key (keyValue): - self._addError ("Element value '%s' does not match key type '%s'!" %(keyValue, keyReference), selectorNode) - - ######################################## - # retrieve nodes/attributes specified by given xPath - # - def _getXPath (self, node, xPath, defaultNamespace, identityConstraint=None): - try: - nodeList, attributeList = node.getXPathList (xPath, defaultNamespace) - except IOError, errstr: - self._addError (errstr, node) - nodeList = attributeList = [] - - if nodeList == [] and attributeList == []: - if identityConstraint == "key": - self.errorHandler.addError ("Key is missing! XPath = '%s'!" %(xPath), node) - elif identityConstraint in ("unique", "keyref"): - self.errorHandler.addWarning ("Identity constraint is missing! XPath = '%s'!" %(xPath), node) - - return nodeList, attributeList - - -######################################## -# define own exception for XML schema validation errors -# -class TagException (StandardError): - def __init__ (self, errstr="", node=None, endTag=0): - self.node = node - self.errstr = errstr - self.endTag = endTag - StandardError.__init__(self) - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/xsvalErrorHandler.py --- a/minixsv/xsvalErrorHandler.py Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -# -# minixsv, Release 0.3 -# file: xsvalErrorHandler.py -# -# XML schema validator classes -# -# history: -# 2004-09-23 rl created -# -# Copyright (c) 2004 by Roland Leuthe. All rights reserved. -# -# -------------------------------------------------------------------- -# The minixsv XML schema validator is -# -# Copyright (c) 2004 by Roland Leuthe -# -# By obtaining, using, and/or copying this software and/or its -# associated documentation, you agree that you have read, understood, -# and will comply with the following terms and conditions: -# -# Permission to use, copy, modify, and distribute this software and -# its associated documentation for any purpose and without fee is -# hereby granted, provided that the above copyright notice appears in -# all copies, and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of -# the author not be used in advertising or publicity -# pertaining to distribution of the software without specific, written -# prior permission. -# -# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD -# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- -# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -# OF THIS SOFTWARE. -# -------------------------------------------------------------------- - -import string -import os - -IGNORE_WARNINGS = 0 -PRINT_WARNINGS = 1 -STOP_ON_WARNINGS = 2 - - -######################################## -# Error-Handler class for XML schema validator -# handles only validator errors, no parser errors! - -class ErrorHandler: - - def __init__(self, errorLimit, warningProc, verbose): - self.errorLimit = errorLimit - self.warningProc = warningProc - self.verbose = verbose - - self.errorList = [] - self.noOfErrors = 0 - self.warningList = [] - - - ######################################## - # add error to errorList (raise exception only if error limit is reached) - - def addError (self, errstr, element=None, endTag=0): - filePath = "" - lineNo = 0 - if element: - filePath = element.getFilePath() - if endTag: - lineNo = element.getEndLineNumber() - else: - lineNo = element.getStartLineNumber() - self.errorList.append ((filePath, lineNo, "ERROR", "%s" %(errstr))) - self.noOfErrors += 1 - if self.noOfErrors == self.errorLimit: - self._raiseXsvalException ("\nError Limit reached!!") - - - ######################################## - # add warning to warningList - - def addWarning (self, warnstr, element=None): - filePath = "" - lineNo = 0 - if element: - filePath = element.getFilePath() - lineNo = element.getStartLineNumber() - self.warningList.append ((filePath, lineNo, "WARNING", warnstr)) - - - ######################################## - # add info string to errorList - - def addInfo (self, infostr, element=None): - filePath = "" - lineNo = 0 - if element: - filePath = element.getFilePath() - lineNo = element.getStartLineNumber() - self.errorList.append ((filePath, lineNo, "INFO", infostr)) - - - ######################################## - # add error to errorList (if given) and raise exception - - def raiseError (self, errstr, element=None): - self.addError (errstr, element) - self._raiseXsvalException () - - - ######################################## - # raise exception with complete errorList as exception string - # (only if errors occurred) - - def flushOutput (self): - if self.warningProc == PRINT_WARNINGS and self.warningList != []: - print self._assembleSortedOutputList(self.warningList) - self.warningList = [] - elif self.warningProc == STOP_ON_WARNINGS: - self.errorList.extend (self.warningList) - - if self.errorList != []: - self._raiseXsvalException () - - - ######################################## - # Private methods - - def _raiseXsvalException (self, additionalInfo=""): - output = self._assembleSortedOutputList(self.errorList) + additionalInfo - self.errorList = self.warningList = [] - raise XsvalError (output) - - - def _assembleSortedOutputList (self, outputList): - outputList.sort() - outputStrList = [] - for outElement in outputList: - outputStrList.append (self._assembleOutString(outElement)) - return string.join (outputStrList, "\n") - - - def _assembleOutString (self, listElement): - fileStr = "" - lineStr = "" - if listElement[0] != "": - if self.verbose: - fileStr = "%s: " %(listElement[0]) - else: - fileStr = "%s: " %(os.path.basename(listElement[0])) - if listElement[1] != 0: - lineStr = "line %d: " %(listElement[1]) - return "%s: %s%s%s" %(listElement[2], fileStr, lineStr, listElement[3]) - - -class XsvalError (StandardError): - pass - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/xsvalSchema.py --- a/minixsv/xsvalSchema.py Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -# -# minixsv, Release 0.3 -# file: xsvalSchema.py -# -# Derived validator class (for validation of schema files) -# -# history: -# 2004-10-07 rl created -# -# Copyright (c) 2004 by Roland Leuthe. All rights reserved. -# -# -------------------------------------------------------------------- -# The minixsv XML schema validator is -# -# Copyright (c) 2004 by Roland Leuthe -# -# By obtaining, using, and/or copying this software and/or its -# associated documentation, you agree that you have read, understood, -# and will comply with the following terms and conditions: -# -# Permission to use, copy, modify, and distribute this software and -# its associated documentation for any purpose and without fee is -# hereby granted, provided that the above copyright notice appears in -# all copies, and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of -# the author not be used in advertising or publicity -# pertaining to distribution of the software without specific, written -# prior permission. -# -# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD -# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- -# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -# OF THIS SOFTWARE. -# -------------------------------------------------------------------- - -from xsvalErrorHandler import * -from xsvalBase import XsValBase - -########################################################### -# Derived validator class for validating one input schema file against the XML rules file - -class XsValSchema (XsValBase): - - ######################################## - # overloaded validate method - # - def validate (self, inputTree, xsdTree): - XsValBase.validate(self, inputTree, xsdTree) - self._checkSchemaSecondLevel() - - - ######################################## - # additional checks for schema files which are not covered by "xsStructs.xsd" - # - def _checkSchemaSecondLevel(self): - self._checkElementNodesSecondLevel() - self._checkGroupNodesSecondLevel() - self._checkAttrGroupNodesSecondLevel() - self._checkAttributeNodesSecondLevel() - - self._checkSimpleTypesSecondLevel() - - - ######################################## - # additional checks for element nodes - # - def _checkElementNodesSecondLevel(self): - self.inputElementDict = {} - for inputNode in self.inputRoot.getChildrenNS(self.inputNSAlias, "element"): - self.inputElementDict[inputNode.getAttribute("name")] = inputNode - - elementNodes = self.inputRoot.getElementsByTagNameNS (self.inputNSAlias, "element") - for elementNode in elementNodes: - if not elementNode.hasAttribute("name") and not elementNode.hasAttribute("ref"): - self._addError ("Element must have 'name' or 'ref' attribute!", elementNode) - continue - - if elementNode.hasAttribute("name") and elementNode.hasAttribute("ref"): - self._addError ("Element must not have 'name' and 'ref' attribute!", elementNode) - continue - - if elementNode.hasAttribute("ref"): - elementRef = self.xmlIf.extractLocalName(elementNode.getAttribute("ref")) - if not self.inputElementDict.has_key(elementRef): - self._addError ("Reference to undefined element '%s'!" %(elementRef), elementNode) - - complexTypeNode = elementNode.getFirstChildNS (self.inputNSAlias, "complexType") - simpleTypeNode = elementNode.getFirstChildNS (self.inputNSAlias, "simpleType") - if elementNode.hasAttribute("type") and (complexTypeNode != None or simpleTypeNode != None): - self._addError ("Element has type attribute and type definition!", elementNode) - if not elementNode.hasAttribute("type") and complexTypeNode == None and simpleTypeNode == None: - self._addWarning ("Element has no type attribute and no type definition!", elementNode) - - minOccurs = elementNode.getAttributeOrDefault("minOccurs", "1") - maxOccurs = elementNode.getAttributeOrDefault("maxOccurs", "1") - if maxOccurs != "unbounded": - if string.atoi(minOccurs) > string.atoi(maxOccurs): - self._addError ("Attribute minOccurs > maxOccurs!", elementNode) - - - ######################################## - # additional checks for group nodes - # - def _checkGroupNodesSecondLevel(self): - self.inputGroupDict = {} - for groupNode in self.inputRoot.getChildrenNS(self.inputNSAlias, "group"): - self.inputGroupDict[groupNode.getAttribute("name")] = groupNode - - groupNodes = self.inputRoot.getElementsByTagNameNS (self.inputNSAlias, "group") - for groupNode in groupNodes: - if groupNode.hasAttribute("ref"): - groupRef = self.xmlIf.extractLocalName(groupNode.getAttribute("ref")) - if not self.inputGroupDict.has_key(groupRef): - self._addError ("Reference to undefined group '%s'!" %(groupRef), groupNode) - - - ######################################## - # additional checks for attributeGroup nodes - # - def _checkAttrGroupNodesSecondLevel(self): - self.inputAttrGroupDict = {} - for attrGroupNode in self.inputRoot.getChildrenNS(self.inputNSAlias, "attrGroup"): - self.inputAttrGroupDict[attrGroupNode.getAttribute("name")] = attrGroupNode - - attrGroupNodes = self.inputRoot.getElementsByTagNameNS (self.inputNSAlias, "attrGroup") - for attrGroupNode in attrGroupNodes: - if attrGroupNode.hasAttribute("ref"): - attrGroupRef = self.xmlIf.extractLocalName(attrGroupNode.getAttribute("ref")) - if not self.inputAttrGroupDict.has_key(attrGroupRef): - self._addError ("Reference to undefined attribute group '%s'!" %(attrGroupRef), attrGroupNode) - - - ######################################## - # additional checks for attribute nodes - # - def _checkAttributeNodesSecondLevel(self): - attributeNodes = self.inputRoot.getElementsByTagNameNS (self.inputNSAlias, "attribute") - for attributeNode in attributeNodes: - if not attributeNode.hasAttribute("name") and not attributeNode.hasAttribute("ref"): - self._addError ("Attribute must have 'name' or 'ref' attribute!", attributeNode) - continue - - if attributeNode.getAttribute("use") == "required" and attributeNode.hasAttribute("default"): - self._addError ("Attribute 'default' is not allowed, because 'use' is 'required'!", attributeNode) - elif attributeNode.hasAttribute("default") and attributeNode.hasAttribute("fixed"): - self._addError ("Attribute must not have 'default' AND 'fixed' attribute!", attributeNode) - - - ######################################## - # additional checks for simple types - # - def _checkSimpleTypesSecondLevel(self): - restrictionNodes, dummy = self.inputRoot.getXPathList (".//simpleType/restriction", self.inputNSAlias) - for restrictionNode in restrictionNodes: - if not restrictionNode.hasAttribute("base") and restrictionNode.getFirstChildNS (self.inputNSAlias, "simpleType") == None: - self._addError ("Simple type restriction must have 'base' attribute or 'simpleType' child tag!", restrictionNode) - - minExcl = restrictionNode.getFirstChildNS(self.inputNSAlias, "minExclusive") - minIncl = restrictionNode.getFirstChildNS(self.inputNSAlias, "minInclusive") - if minExcl != None and minIncl != None: - self._addError ("Restriction attributes 'minExclusive' and 'minInclusive' cannot be defined together!", restrictionNode) - maxExcl = restrictionNode.getFirstChildNS(self.inputNSAlias, "maxExclusive") - maxIncl = restrictionNode.getFirstChildNS(self.inputNSAlias, "maxInclusive") - if maxExcl != None and maxIncl != None: - self._addError ("Restriction attributes 'maxExclusive' and 'maxInclusive' cannot be defined together!", restrictionNode) - - listNodes = self.inputRoot.getElementsByTagNameNS (self.inputNSAlias, "list") - for listNode in listNodes: - if not listNode.hasAttribute("itemType") and restrictionNode.getFirstChildNS (self.inputNSAlias, "simpleType") == None: - self._addError ("List type must have 'itemType' attribute or 'simpleType' child tag!", listNode) - - diff -r aaa80b48bead -r dcfe7c07ba1c minixsv/xsvalSimpleTypes.py --- a/minixsv/xsvalSimpleTypes.py Tue Jan 22 10:57:41 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,332 +0,0 @@ -# -# # minixsv, Release 0.3 -# file: xsvalSimpleTypes.py -# -# class for validation of XML schema simple types -# -# history: -# 2004-09-09 rl created -# -# Copyright (c) 2004 by Roland Leuthe. All rights reserved. -# -# -------------------------------------------------------------------- -# The minixsv XML schema validator is -# -# Copyright (c) 2004 by Roland Leuthe -# -# By obtaining, using, and/or copying this software and/or its -# associated documentation, you agree that you have read, understood, -# and will comply with the following terms and conditions: -# -# Permission to use, copy, modify, and distribute this software and -# its associated documentation for any purpose and without fee is -# hereby granted, provided that the above copyright notice appears in -# all copies, and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of -# the author not be used in advertising or publicity -# pertaining to distribution of the software without specific, written -# prior permission. -# -# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD -# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- -# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -# OF THIS SOFTWARE. -# -------------------------------------------------------------------- - - -import sys -import string -import re - - -class XsSimpleTypeVal: - - def __init__ (self, parent): - self.parent = parent - self.xmlIf = parent.xmlIf - self.xsdNSAlias = parent.xsdNSAlias - self.xsdTree = parent.xsdTree - - - ######################################## - # validate given value against simpleType - # - def checkSimpleType (self, attrName, typeName, attributeValue, returnDict): - localTypeName = self.xmlIf.extractLocalName(typeName) - if self.parent.xsdTypeDict.has_key(localTypeName): - typedefNode = self.parent.xsdTypeDict[localTypeName] - if typedefNode.getTagName () == self.xsdNSAlias + "simpleType": - self.checkSimpleTypeDef (typedefNode, attrName, attributeValue, returnDict) - else: - raise SimpleTypeError("Type '%s' must be simple type!" %(typeName)) - else: - try: - validateBaseType (typeName, attributeValue, returnDict) - except BaseTypeError, errstr: - raise SimpleTypeError("Value of '%s' (%s) %s" %(attrName, attributeValue, errstr)) - - - ######################################## - # validate given value against simpleType node - # - def checkSimpleTypeDef (self, xsdElement, attrName, attributeValue, returnDict): - restrictionElement = xsdElement.getFirstChildNS(self.xsdNSAlias, "restriction") - listElement = xsdElement.getFirstChildNS(self.xsdNSAlias, "list") - unionElement = xsdElement.getFirstChildNS(self.xsdNSAlias, "union") - if restrictionElement != None: - self._checkRestrictionTag (restrictionElement, attrName, attributeValue, returnDict) - elif listElement != None: - self._checkListTag (listElement, attrName, attributeValue, returnDict) - elif unionElement != None: - self._checkUnionTag (unionElement, attrName, attributeValue, returnDict) - - ######################################## - # validate given value against restriction node - # - def _checkRestrictionTag (self, xsdElement, attrName, attributeValue, returnDict): - # first check against base type - baseType = xsdElement.getAttribute("base") - if baseType != None: - self.checkSimpleType (attrName, baseType, attributeValue, returnDict) - else: - baseTypeNode = xsdElement.getFirstChildNS(self.xsdNSAlias, "simpleType") - self.checkSimpleTypeDef (baseTypeNode, attrName, attributeValue, returnDict) - - minExcl = xsdElement.getFirstChildNS(self.xsdNSAlias, "minExclusive") - minIncl = xsdElement.getFirstChildNS(self.xsdNSAlias, "minInclusive") - maxExcl = xsdElement.getFirstChildNS(self.xsdNSAlias, "maxExclusive") - maxIncl = xsdElement.getFirstChildNS(self.xsdNSAlias, "maxInclusive") - - if minExcl != None: - minExclReturnDict = {} - minExclValue = minExcl.getAttribute("value") - self.checkSimpleType (attrName, baseType, minExclValue, minExclReturnDict) - if returnDict.has_key("orderedValue") and minExclReturnDict.has_key("orderedValue"): - if returnDict["orderedValue"] <= minExclReturnDict["orderedValue"]: - raise SimpleTypeError ("Value of %s (%s) is <= minExclusive (%s)" %(attrName, attributeValue, minExclValue)) - elif minIncl != None: - minInclReturnDict = {} - minInclValue = minIncl.getAttribute("value") - self.checkSimpleType (attrName, baseType, minInclValue, minInclReturnDict) - if returnDict.has_key("orderedValue") and minInclReturnDict.has_key("orderedValue"): - if returnDict["orderedValue"] < minInclReturnDict["orderedValue"]: - raise SimpleTypeError ("Value of %s (%s) is < minInclusive (%s)" %(attrName, attributeValue, minInclValue)) - if maxExcl != None: - maxExclReturnDict = {} - maxExclValue = maxExcl.getAttribute("value") - self.checkSimpleType (attrName, baseType, maxExclValue, maxExclReturnDict) - if returnDict.has_key("orderedValue") and maxExclReturnDict.has_key("orderedValue"): - if returnDict["orderedValue"] >= maxExclReturnDict["orderedValue"]: - raise SimpleTypeError ("Value of %s (%s) is >= maxExclusive (%s)" %(attrName, attributeValue, maxExclValue)) - elif maxIncl != None: - maxInclReturnDict = {} - maxInclValue = maxIncl.getAttribute("value") - self.checkSimpleType (attrName, baseType, maxInclValue, maxInclReturnDict) - if returnDict.has_key("orderedValue") and maxInclReturnDict.has_key("orderedValue"): - if returnDict["orderedValue"] > maxInclReturnDict["orderedValue"]: - raise SimpleTypeError ("Value of %s (%s) is > maxInclusive (%s)" %(attrName, attributeValue, maxInclValue)) - - totalDigitsNode = xsdElement.getFirstChildNS(self.xsdNSAlias, "totalDigits") - if totalDigitsNode != None: - totalDigitsValue = totalDigitsNode.getAttribute("value") - if totalDigitsNode.getAttribute("fixed") == "true": - if len(re.findall("\d" ,attributeValue)) != string.atoi(totalDigitsValue): - raise SimpleTypeError ("Total number of digits != %s for %s (%s)" %(totalDigitsValue, attrName, attributeValue)) - else: - if len(re.findall("\d" ,attributeValue)) > string.atoi(totalDigitsValue): - raise SimpleTypeError ("Total number of digits > %s for %s (%s)" %(totalDigitsValue, attrName, attributeValue)) - fractionDigitsNode = xsdElement.getFirstChildNS(self.xsdNSAlias, "fractionDigits") - if fractionDigitsNode != None: - fractionDigitsValue = fractionDigitsNode.getAttribute("value") - result = re.search("(?P\d+)(?P\.)(?P\d+)" ,attributeValue) - if result != None: - numberOfFracDigits = len (result.group('fracDigits')) - else: - numberOfFracDigits = 0 - if fractionDigitsNode.getAttribute("fixed") == "true" and numberOfFracDigits != string.atoi(fractionDigitsValue): - raise SimpleTypeError ("Fraction number of digits != %s for %s (%s)" %(fractionDigitsValue, attrName, attributeValue)) - elif numberOfFracDigits > string.atoi(fractionDigitsValue): - raise SimpleTypeError ("Fraction number of digits > %s for %s (%s)" %(fractionDigitsValue, attrName, attributeValue)) - - if returnDict.has_key("length"): - lengthNode = xsdElement.getFirstChildNS(self.xsdNSAlias, "length") - if lengthNode != None: - length = string.atoi(lengthNode.getAttribute("value")) - if returnDict["length"] != length: - raise SimpleTypeError ("Length of %s (%s) must be %d!" %(attrName, attributeValue, length)) - minLengthNode = xsdElement.getFirstChildNS(self.xsdNSAlias, "minLength") - if minLengthNode != None: - minLength = string.atoi(minLengthNode.getAttribute("value")) - if returnDict["length"] < minLength: - raise SimpleTypeError ("Length of %s (%s) must be >= %d!" %(attrName, attributeValue, minLength)) - maxLengthNode = xsdElement.getFirstChildNS(self.xsdNSAlias, "maxLength") - if maxLengthNode != None: - maxLength = string.atoi(maxLengthNode.getAttribute("value")) - if returnDict["length"] > maxLength: - raise SimpleTypeError ("Length of %s (%s) must be <= %d!" %(attrName, attributeValue, maxLength)) - - enumerationElementList = xsdElement.getChildrenNS(self.xsdNSAlias, "enumeration") - if enumerationElementList != []: - for enumeration in enumerationElementList: - if enumeration.getAttribute ("value") == attributeValue: - break - else: - raise SimpleTypeError ("Enumeration value '%s' not allowed!" %(attributeValue)) - - patternNode = xsdElement.getFirstChildNS(self.xsdNSAlias, "pattern") - if patternNode != None: - rePattern = patternNode.getAttribute("value") - regexObj = re.match(rePattern, attributeValue) - if not regexObj or regexObj.end() != len(attributeValue): - raise SimpleTypeError ("Attribute value '%s' does not match pattern '%s'!" %(attributeValue, rePattern)) - - whiteSpace = xsdElement.getFirstChildNS(self.xsdNSAlias, "whiteSpace") - if whiteSpace != None: - wsAction = whiteSpace.getAttribute("value") - if wsAction == "replace": - normalizedValue = self._normalizeString(attributeValue) - if normalizedValue != attributeValue: - returnDict["adaptedAttrValue"] = normalizedValue - elif wsAction == "collapse": - collapsedValue = self._collapseString(attributeValue) - if collapsedValue != attributeValue: - returnDict["adaptedAttrValue"] = collapsedValue - - - ######################################## - # validate given value against list node - # - def _checkListTag (self, xsdElement, attrName, attributeValue, returnDict): - if attributeValue != "": - itemType = xsdElement.getAttribute ("itemType") - # substitute multiple whitespace characters by a single ' ' - collapsedValue = self._collapseString(attributeValue) - if collapsedValue != attributeValue: - returnDict["adaptedAttrValue"] = collapsedValue - - # divide up attributeValue => store it into list - attributeList = string.split(collapsedValue, " ") - for attrValue in attributeList: - elementReturnDict = {} - if itemType != None: - self.checkSimpleType (attrName, itemType, attrValue, elementReturnDict) - else: - itemTypeNode = xsdElement.getFirstChildNS(self.xsdNSAlias, "simpleType") - self.checkSimpleTypeDef (itemTypeNode, attrName, attrValue, elementReturnDict) - - returnDict["length"] = len(attributeList) - else: - returnDict["length"] = 0 - - - ######################################## - # validate given value against union node - # - def _checkUnionTag (self, xsdElement, attrName, attributeValue, returnDict): - memberTypes = xsdElement.getAttribute ("memberTypes") - if memberTypes != None: - # substitute multiple whitespace characters by a single ' ' - # divide up attributeValue => store it into list - for memberType in string.split(self._collapseString(memberTypes), " "): - try: - self.checkSimpleType (attrName, memberType, attributeValue, returnDict) - return - except SimpleTypeError, errstr: - pass - - # memberTypes and additional type definitions is legal! - for childSimpleType in xsdElement.getChildrenNS(self.xsdNSAlias, "simpleType"): - try: - self.checkSimpleTypeDef (childSimpleType, attrName, attributeValue, returnDict) - return - except SimpleTypeError, errstr: - pass - - raise SimpleTypeError ("%s (%s) is no valid union member type (%s)!" %(attrName, attributeValue, memberTypes)) - - - ######################################## - # substitute multiple whitespace characters by a single ' ' - # - def _collapseString (self, strValue): - return re.sub('\s+', ' ', strValue) - - ######################################## - # substitute each whitespace characters by a single ' ' - # - def _normalizeString (self, strValue): - return re.sub('\s', ' ', strValue) - - - - -def validateBaseType (simpleType, attributeValue, returnDict): -# TODO: Many base types are not completely defined by datatypes.xsd - simpleTypeDict = {"xsd:string": _checkStringType, - "xsd:hexBinary": _checkHexBinaryType, - "xsd:integer": _checkIntegerType, - "xsd:boolean": _checkBooleanType, - "xsd:QName": _checkQNameType, - } - - simpleType = string.replace(simpleType, "xs:", "xsd:") - if simpleTypeDict.has_key (simpleType): - simpleTypeDict[simpleType] (simpleType, attributeValue, returnDict) - - elif simpleType != "xsd:anySimpleType": - if simpleType in ("xsd:decimal", "xsd:float", "xsd:double", "xsd:base64Binary", "xsd:anyURI", "xsd:NOTATION", - "xsd:duration", "xsd:dateTime", "xsd:time", "xsd:date", - "xsd:gYearMonth", "xsd:gMonthDay", "xsd:gYear", "xsd:gMonth", "xsd:gDay"): - print "INFO: Check of simple type '%s' currently not supported!" %(simpleType) - else: - # TODO: Fehler im XSD-File => Check muss an anderer Stelle erfolgen - raise BaseTypeError("uses unknown type '%s'!" %(simpleType)) - - -def _checkStringType (simpleType, attributeValue, returnDict): - # all valid?? - returnDict["length"] = len(attributeValue) - -def _checkHexBinaryType (simpleType, attributeValue, returnDict): - _checkIntegerRange (attributeValue, 16, 0, sys.maxint, returnDict) - returnDict["length"] = len(attributeValue) - -def _checkIntegerType (simpleType, attributeValue, returnDict): - _checkIntegerRange (attributeValue, 10, -sys.maxint-1, sys.maxint, returnDict) - -def _checkBooleanType (simpleType, attributeValue, returnDict): - if attributeValue not in ("true", "false", "1", "0"): - raise BaseTypeError("is not a boolean value!") - -def _checkQNameType (simpleType, attributeValue, returnDict): - # TODO: fill - returnDict["length"] = len(attributeValue) - -def _checkIntegerRange (attributeValue, base, minBase, maxBase, returnDict): - try: - value = string.atoi (attributeValue, base=base) - except: - if base == 16: - raise BaseTypeError("is not a hexadecimal value!") - else: - raise BaseTypeError("is not an integer!") - - if value < minBase or value > maxBase: - raise BaseTypeError("is out of range (%d..%d)!" %(minBase, maxBase)) - - returnDict["orderedValue"] = value - - - -######################################## -# define own exception for XML schema validation errors -# -class SimpleTypeError (StandardError): - pass - -class BaseTypeError (StandardError): - pass