#!/usr/bin/env python3 # validate_padnext_2_12.py # Validate PADneXt 2.12 ADL and AUF XML files against XSDs using lxml. # Usage: # python validate_padnext_2_12.py [ ...] from lxml import etree from pathlib import Path import sys import textwrap def load_schema(xsd_path: Path) -> etree.XMLSchema: parser = etree.XMLParser(remove_blank_text=True) doc = etree.parse(str(xsd_path), parser) return etree.XMLSchema(doc) def validate(xml_path: Path, schema: etree.XMLSchema): parser = etree.XMLParser(remove_blank_text=True) doc = etree.parse(str(xml_path), parser) ok = schema.validate(doc) return ok, schema.error_log def main(argv): if len(argv) < 3 or len(argv[1:]) % 2 != 0: print("Usage: python validate_padnext_2_12.py [ ...]") return 2 # Process pairs for i in range(1, len(argv), 2): xml_path = Path(argv[i]) xsd_path = Path(argv[i+1]) print(f"— Validate —") print(f" XML: {xml_path}") print(f" XSD: {xsd_path}") try: schema = load_schema(xsd_path) except Exception as e: print(" ❌ Failed to load schema:") print(textwrap.indent(str(e), " ")) print() continue try: ok, log = validate(xml_path, schema) except Exception as e: print(" ❌ Exception during validation:") print(textwrap.indent(str(e), " ")) print() continue if ok: print(" ✅ VALID\n") else: print(" ❌ NOT VALID") for entry in log: loc = f"{Path(entry.filename).name if entry.filename else xml_path.name}:{entry.line}:{entry.column}" print(f" - {loc}: {entry.message}") print() return 0 if __name__ == "__main__": sys.exit(main(sys.argv))