import logging import glob import sys from pathlib import Path from pprint import pprint from lxml import etree from xml.etree.ElementTree import ParseError from xmlschema import XMLSchema, XMLSchemaParseError def BuildSchemaDictonary (fileList): if len(fileList) == 0: logging.info("No schema files provided") return [] logging.info("Schema locations:") schemaLocations = [] for schemaFile in fileList: try: xs = XMLSchema(schemaFile, validation='skip') schemaLocations.append((xs.default_namespace, str(Path(schemaFile).resolve()))) logging.info(" [ {0} -> {1} ]".format(xs.default_namespace, schemaFile)) except ParseError as ex: logging.warning (" [ {0} failed to parse: {1} ]".format(schemaFile, ex)) return schemaLocations def BuildSchema (coreFile, fileList = None): schemaLocations = [] if fileList and len(fileList) > 0: schemaLocations = BuildSchemaDictonary(fileList) coreSchema = XMLSchema(str(Path(coreFile)), locations=schemaLocations) return coreSchema def ValidateXSDFiles (fileList): if len(fileList) == 0: logging.info("No schema files provided") return {} schemaLocations = BuildSchemaDictonary(fileList) errors = {} logging.info("Schema validation:") for schemaFile in fileList: try: schema = XMLSchema(schemaFile, locations = schemaLocations) logging.info(schemaFile + ": OK") errors[schemaFile] = [] except XMLSchemaParseError as ex: logging.warning(schemaFile + ": Failed validation ({0})".format(ex.message)) if (ex.schema_url) and (ex.schema_url != ex.origin_url): logging.warning(" Error comes from {0}, suppressing".format(ex.schema_url)) else: errors[schemaFile] = [ex] return errors def ValidateAllXSDFilesInPath (path): globPattern = str(Path(path)) + '/*.xsd' logging.info("Searching: " + globPattern) schemaGlob = glob.glob(globPattern, recursive=True) return ValidateXSDFiles(schemaGlob) def ValidateInstanceDocuments (coreFile, supportingSchemas, instanceDocs): if (instanceDocs is None) or len(instanceDocs) == 0: logging.warning ("No instance documents provided") return [] schema = BuildSchema(coreFile, supportingSchemas) errors = [] for instanceDoc in instanceDocs: try: schema.validate(instanceDoc) logging.info ("{0} passed validation".format(instanceDoc)) except Exception as ex: logging.error ("{0} failed validation: {1}".format(instanceDoc, ex)) return errors if __name__ == '__main__': results = ValidateAllXSDFilesInPath("./") print ("XSD validation checks:") print ("-----------------------------") errorCount = 0 for fileName, errors in results.items(): if len(errors) > 0: errorCount += len(errors) print (f" {fileName}: {len(errors)} errors") for error in errors: if isinstance(error, XMLSchemaParseError): print (error.msg) else: print (f" {str(error)}") else: print (f" {fileName}: OK") print ("-----------------------------") print (f"{errorCount} errors detected") exit(errorCount)