00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 __all__ = [
00048
00049 "addUserSpecXmlIfClass",
00050 "parseAndValidate",
00051 "parseAndValidateString",
00052 "parseAndValidateXmlInput",
00053 "parseAndValidateXmlInputString",
00054 "parseAndValidateXmlSchema",
00055 "parseAndValidateXmlSchemaString",
00056 "XsValidator",
00057 ]
00058
00059
00060 import string
00061 from .. import genxmlif
00062 from ..minixsv import *
00063 from xsvalErrorHandler import ErrorHandler
00064 from xsvalXmlIf import XsvXmlElementWrapper
00065 from xsvalBase import XsValBase
00066 from xsvalSchema import XsValSchema
00067
00068
00069 __author__ = "Roland Leuthe <roland@leuthe-net.de>"
00070 __date__ = "08. August 2008"
00071 __version__ = "0.9.0"
00072
00073
00074 _XS_VAL_DEFAULT_ERROR_LIMIT = 20
00075
00076 rulesTreeWrapper = None
00077
00078
00079
00080
00081
00082 def getVersion ():
00083 return __version__
00084
00085
00086
00087
00088
00089 def addUserSpecXmlIfClass (xmlIfKey, factory):
00090 if not _xmlIfDict.has_key(xmlIfKey):
00091 _xmlIfDict[xmlIfKey] = factory
00092 else:
00093 raise KeyError, "xmlIfKey %s already implemented!" %(xmlIfKey)
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 def parseAndValidate (inputFile, xsdFile=None, **kw):
00105 return parseAndValidateXmlInput (inputFile, xsdFile, 1, **kw)
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 def parseAndValidateString (inputText, xsdText=None, **kw):
00117 return parseAndValidateXmlInputString (inputText, xsdText, 1, **kw)
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 def parseAndValidateXmlInput (inputFile, xsdFile=None, validateSchema=0, **kw):
00129 xsValidator = XsValidator (**kw)
00130
00131 inputTreeWrapper = xsValidator.parse (inputFile)
00132
00133 return xsValidator.validateXmlInput (inputFile, inputTreeWrapper, xsdFile, validateSchema)
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 def parseAndValidateXmlInputString (inputText, xsdText=None, baseUrl="", validateSchema=0, **kw):
00145 xsValidator = XsValidator (**kw)
00146
00147 inputTreeWrapper = xsValidator.parseString (inputText, baseUrl)
00148
00149 return xsValidator.validateXmlInputString (inputTreeWrapper, xsdText, validateSchema)
00150
00151
00152
00153
00154
00155 def parseAndValidateXmlSchema (xsdFile, **kw):
00156 xsValidator = XsValidator (**kw)
00157
00158 xsdTreeWrapper = xsValidator.parse (xsdFile)
00159
00160 return xsValidator.validateXmlSchema (xsdFile, xsdTreeWrapper)
00161
00162
00163
00164
00165
00166 def parseAndValidateXmlSchemaString (xsdText, **kw):
00167 xsValidator = XsValidator (**kw)
00168
00169 xsdTreeWrapper = xsValidator.parseString (xsdText)
00170
00171 return xsValidator.validateXmlSchema ("", xsdTreeWrapper)
00172
00173
00174
00175
00176
00177 class XsValidator:
00178 def __init__(self, xmlIfClass=XMLIF_MINIDOM,
00179 elementWrapperClass=XsvXmlElementWrapper,
00180 warningProc=IGNORE_WARNINGS, errorLimit=_XS_VAL_DEFAULT_ERROR_LIMIT,
00181 verbose=0, useCaching=1, processXInclude=1):
00182
00183 self.warningProc = warningProc
00184 self.errorLimit = errorLimit
00185 self.verbose = verbose
00186
00187
00188 self.xmlIf = _xmlIfDict[xmlIfClass](verbose, useCaching, processXInclude)
00189 self.xmlIf.setElementWrapperClass (elementWrapperClass)
00190
00191
00192 self.errorHandler = ErrorHandler (errorLimit, warningProc, verbose)
00193
00194 self.schemaDependancyList = []
00195
00196
00197
00198
00199
00200 def getVersion (self):
00201 return __version__
00202
00203
00204
00205
00206
00207
00208 def parse (self, file, baseUrl="", ownerDoc=None):
00209 self._verbosePrint ("Parsing %s..." %(file))
00210 return self.xmlIf.parse(file, baseUrl, ownerDoc)
00211
00212
00213
00214
00215
00216 def parseString (self, text, baseUrl=""):
00217 self._verbosePrint ("Parsing XML text string...")
00218 return self.xmlIf.parseString(text, baseUrl)
00219
00220
00221
00222
00223
00224 def validateXmlInput (self, xmlInputFile, inputTreeWrapper, xsdFile=None, validateSchema=0):
00225
00226 xsdTreeWrapperList = self._readReferencedXsdFiles(inputTreeWrapper, validateSchema)
00227 if xsdTreeWrapperList == []:
00228
00229 if xsdFile != None:
00230 xsdTreeWrapper = self.parse (xsdFile)
00231 xsdTreeWrapperList.append(xsdTreeWrapper)
00232
00233 if validateSchema:
00234 self.validateXmlSchema (xsdFile, xsdTreeWrapper)
00235 else:
00236 self.errorHandler.raiseError ("No schema file specified!")
00237
00238 self._validateXmlInput (xmlInputFile, inputTreeWrapper, xsdTreeWrapperList)
00239 for xsdTreeWrapper in xsdTreeWrapperList:
00240 xsdTreeWrapper.unlink()
00241 return inputTreeWrapper
00242
00243
00244
00245
00246 def validateXmlInputString (self, inputTreeWrapper, xsdText=None, validateSchema=0):
00247
00248 xsdTreeWrapperList = self._readReferencedXsdFiles(inputTreeWrapper, validateSchema)
00249 if xsdTreeWrapperList == []:
00250
00251 if xsdText != None:
00252 xsdFile = "schema text"
00253 xsdTreeWrapper = self.parseString (xsdText)
00254 xsdTreeWrapperList.append(xsdTreeWrapper)
00255
00256 if validateSchema:
00257 self.validateXmlSchema (xsdFile, xsdTreeWrapper)
00258 else:
00259 self.errorHandler.raiseError ("No schema specified!")
00260
00261 self._validateXmlInput ("input text", inputTreeWrapper, xsdTreeWrapperList)
00262 for xsdTreeWrapper in xsdTreeWrapperList:
00263 xsdTreeWrapper.unlink()
00264 return inputTreeWrapper
00265
00266
00267
00268
00269
00270 def validateXmlSchema (self, xsdFile, xsdTreeWrapper):
00271
00272 global rulesTreeWrapper
00273 if rulesTreeWrapper == None:
00274 rulesTreeWrapper = self.parse(os.path.join (MINIXSV_DIR, "XMLSchema.xsd"))
00275
00276 self._verbosePrint ("Validating %s..." %(xsdFile))
00277 xsvGivenXsdFile = XsValSchema (self.xmlIf, self.errorHandler, self.verbose)
00278 xsvGivenXsdFile.validate(xsdTreeWrapper, [rulesTreeWrapper,])
00279 self.schemaDependancyList.append (xsdFile)
00280 self.schemaDependancyList.extend (xsvGivenXsdFile.xsdIncludeDict.keys())
00281 xsvGivenXsdFile.unlink()
00282 self.errorHandler.flushOutput()
00283 return xsdTreeWrapper
00284
00285
00286
00287
00288
00289 def _validateXmlInput (self, xmlInputFile, inputTreeWrapper, xsdTreeWrapperList):
00290 self._verbosePrint ("Validating %s..." %(xmlInputFile))
00291 xsvInputFile = XsValBase (self.xmlIf, self.errorHandler, self.verbose)
00292 xsvInputFile.validate(inputTreeWrapper, xsdTreeWrapperList)
00293 xsvInputFile.unlink()
00294 self.errorHandler.flushOutput()
00295
00296
00297
00298
00299
00300 def _readReferencedXsdFiles (self, inputTreeWrapper, validateSchema):
00301 xsdTreeWrapperList = []
00302
00303 xsdFileList = self._retrieveReferencedXsdFiles (inputTreeWrapper)
00304 for namespace, xsdFile in xsdFileList:
00305 try:
00306 xsdTreeWrapper = self.parse (xsdFile, inputTreeWrapper.getRootNode().getAbsUrl())
00307 except IOError, e:
00308 if e.errno == 2:
00309 self.errorHandler.raiseError ("XML schema file %s not found!" %(xsdFile), inputTreeWrapper.getRootNode())
00310 else:
00311 raise IOError(e.errno, e.strerror, e.filename)
00312
00313 xsdTreeWrapperList.append(xsdTreeWrapper)
00314
00315 if validateSchema:
00316 self.validateXmlSchema (xsdFile, xsdTreeWrapper)
00317
00318 if namespace != xsdTreeWrapper.getRootNode().getAttributeOrDefault("targetNamespace", None):
00319 self.errorHandler.raiseError ("Namespace of 'schemaLocation' attribute doesn't match target namespace of %s!" %(xsdFile), inputTreeWrapper.getRootNode())
00320
00321 return xsdTreeWrapperList
00322
00323
00324
00325
00326
00327 def _retrieveReferencedXsdFiles (self, inputTreeWrapper):
00328
00329 inputRootNode = inputTreeWrapper.getRootNode()
00330 xsdFileList = []
00331
00332 if inputRootNode.hasAttribute((XSI_NAMESPACE, "schemaLocation")):
00333 attributeValue = inputRootNode.getAttribute((XSI_NAMESPACE, "schemaLocation"))
00334 attrValList = string.split(attributeValue)
00335 if len(attrValList) % 2 == 0:
00336 for i in range(0, len(attrValList), 2):
00337 xsdFileList.append((attrValList[i], attrValList[i+1]))
00338 else:
00339 self.errorHandler.raiseError ("'schemaLocation' attribute must have even number of URIs (pairs of namespace and xsdFile)!")
00340
00341 if inputRootNode.hasAttribute((XSI_NAMESPACE, "noNamespaceSchemaLocation")):
00342 attributeValue = inputRootNode.getAttribute((XSI_NAMESPACE, "noNamespaceSchemaLocation"))
00343 attrValList = string.split(attributeValue)
00344 for attrVal in attrValList:
00345 xsdFileList.append ((None, attrVal))
00346
00347 return xsdFileList
00348
00349
00350
00351
00352 def _verbosePrint (self, text):
00353 if self.verbose:
00354 print text
00355
00356
00357
00358
00359
00360 def _interfaceFactoryMinidom (verbose, useCaching, processXInclude):
00361 return genxmlif.chooseXmlIf(genxmlif.XMLIF_MINIDOM, verbose, useCaching, processXInclude)
00362
00363 def _interfaceFactory4Dom (verbose, useCaching, processXInclude):
00364 return genxmlif.chooseXmlIf(genxmlif.XMLIF_4DOM, verbose, useCaching, processXInclude)
00365
00366 def _interfaceFactoryElementTree (verbose, useCaching, processXInclude):
00367 return genxmlif.chooseXmlIf(genxmlif.XMLIF_ELEMENTTREE, verbose, useCaching, processXInclude)
00368
00369
00370 _xmlIfDict = {XMLIF_MINIDOM :_interfaceFactoryMinidom,
00371 XMLIF_4DOM :_interfaceFactory4Dom,
00372 XMLIF_ELEMENTTREE:_interfaceFactoryElementTree}
00373