Validating DCCs

The dcclib.validation module validates DCCs against an XSD schema and against Schematron business rules. This guide walks through both from Python; see the dcclib validate reference for the command-line equivalent.

XSD validation

An XsdValidator can be constructed for a specific bundled schema version with from_version. Its validate_file method returns an XsdValidationResult describing the outcome.

The following example validates a valid DCC against schema version "3.3.0":

from dcclib.validation import XsdValidator

schema_validator = XsdValidator.from_version("3.3.0")
result = schema_validator.validate_file(dcc_xml_path)
print("Is valid:", result.is_valid)
print("Errors:", len(result.errors))

When a document is invalid, each entry in result.errors carries the error type, location, and message:

from dcclib.validation import XsdValidator

schema_validator = XsdValidator.from_version("3.3.0")
result = schema_validator.validate_file(invalid_schema_xml_path)
print("Is valid:", result.is_valid)
print("Errors:", len(result.errors))
for error in result.errors:
    print(f"[{error.type_name} - {error.line}:{error.column}] {error.message}")

Custom XSD schemas

A custom schema can be loaded with from_file and used exactly like a bundled one:

from dcclib.validation import XsdValidator

schema_validator = XsdValidator.from_file(custom_xsd_path)
result = schema_validator.validate_file(dcc_xml_path)
print("Is valid:", result.is_valid)
print("Errors:", len(result.errors))
for error in result.errors:
    print(f"[{error.type_name} - {error.line}:{error.column}] {error.message}")

Schematron validation

Schematron extends XSD validation with more complex, rule-based checks. A SchematronValidator for the bundled DCC ruleset is created with for_dcc. Its result exposes both failed_assertions and successful_reports:

from dcclib.validation import SchematronValidator

schematron_validator = SchematronValidator.for_dcc()
result = schematron_validator.validate_file(dcc_xml_path)
print("Is valid:", result.is_valid)
print("Failed assertions:", len(result.failed_assertions))
print("Successful reports:", len(result.successful_reports))
for report in result.successful_reports:
    print(f"[{report.role}] {report.text}")

Failed assertions describe the rules a document violates:

from dcclib.validation import SchematronValidator

schematron_validator = SchematronValidator.for_dcc()
result = schematron_validator.validate_file(invalid_schematron_xml_path)
print("Is valid:", result.is_valid)
print("Failed assertions:", len(result.failed_assertions))
for assertion in result.failed_assertions[:5]:
    print(f"[{assertion.role}] {assertion.text}")

Custom Schematron rulesets

A custom .sch file (or a pre-compiled SVRL document) is loaded with from_file:

from dcclib.validation import SchematronValidator

schematron_validator = SchematronValidator.from_file(custom_schematron_path)
result = schematron_validator.validate_file(dcc_xml_path)
print("Is valid:", result.is_valid)
print("Successful reports:", len(result.successful_reports))
for report in result.successful_reports:
    print(f"[{report.role}] {report.text}")

Note

When a .sch file is provided, dcclib compiles it to SVRL on the fly using Saxon (via saxonche), adding a one-time compilation step.

Validating in CI

Because the CLI ships as a container image, DCC files can be validated as part of a GitLab CI pipeline. The job below validates every *.xml file in the repository against the XSD schema:

validate_examples:
  image:
    name: registry.gitlab1.ptb.de/d-ptb/dcc/dcclib/cli
    entrypoint: [""]
  script:
    - for file in *.xml; do
        echo "Validating $file";
        dcclib validate xsd $file;
      done

The dcclib validate xsd command exits non-zero when a file is invalid, failing the job so malformed certificates are caught before they are merged.

See also