check_xsd.py 3.35 KB
Newer Older
canterburym's avatar
canterburym committed
1
2
import logging

canterburym's avatar
canterburym committed
3
4
5
6
7
import glob
import sys
from pathlib import Path
from pprint import pprint

canterburym's avatar
canterburym committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
canterburym's avatar
canterburym committed
37
38


canterburym's avatar
canterburym committed
39
40
41
42
43
44
45
def ValidateXSDFiles (fileList):
    if len(fileList) == 0:
        logging.info("No schema files provided")
        return {}
    
    schemaLocations = BuildSchemaDictonary(fileList)
    errors = {}
canterburym's avatar
canterburym committed
46

canterburym's avatar
canterburym committed
47
48
49
50
51
52
53
54
55
56
57
58
59
    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
canterburym's avatar
canterburym committed
60
61


canterburym's avatar
canterburym committed
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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("./")
canterburym's avatar
canterburym committed
89

canterburym's avatar
canterburym committed
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    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")
canterburym's avatar
canterburym committed
104

canterburym's avatar
canterburym committed
105
106
107
    print ("-----------------------------")
    print (f"{errorCount} errors detected")
    exit(errorCount)