#!/usr/bin/env python3 """Pārbauda visas data/*.xml datnes: 1. atbilst XSD schemas/mk-noteikumi-0.1.xsd (arī identifikatoru unikalitāte); 2. datnes nosaukums = noteikumu identifikators, un identifikators = gads un numurs no Act; 3. Source/SHA256 = sources/.txt sha256; 4. katrs teksts (Text, Note, Title, LegalBasis, Lead, Item, Line, Heading) ir avota teksta datnē tādā pašā secībā; 5. katra elementa identifikators sākas ar noteikumu identifikatoru, punkta identifikators atbilst drukātajam numuram. python3 tools/validate.py → kopsavilkums; izejas kods 1, ja kāda pārbaude neizdodas """ import glob import hashlib import os import re import sys from lxml import etree ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) NS = {"n": "urn:pppa:vpk:mk-noteikumi:0.1"} SUPC = "⁰¹²³⁴⁵⁶⁷⁸⁹" schema = etree.XMLSchema(etree.parse(f"{ROOT}/schemas/mk-noteikumi-0.1.xsd")) def pid(num): return "p" + re.sub("[" + SUPC + "]+", lambda m: "s" + m.group(0).translate(str.maketrans(SUPC, "0123456789")), num) def check(path): errs = [] doc = etree.parse(path) if not schema.validate(doc): errs += [f"XSD: {e.message}" for e in list(schema.error_log)[:5]] r = doc.getroot() did = r.get("id") if os.path.basename(path) != f"{did}.xml": errs.append(f"datnes nosaukums {os.path.basename(path)} ≠ {did}.xml") num, adopted = r.findtext("n:Act/n:Number", namespaces=NS), r.findtext("n:Act/n:Adopted", namespaces=NS) or "" if did != f"lv-mkn-{adopted[:4]}-{num}": errs.append(f"identifikators {did} ≠ lv-mkn-{adopted[:4]}-{num}") src = f"{ROOT}/{r.findtext('n:Source/n:File', namespaces=NS)}" if not os.path.exists(src): return errs + [f"nav avota datnes {src}"] body = open(src, encoding="utf-8").read() if hashlib.sha256(body.encode("utf-8")).hexdigest() != r.findtext("n:Source/n:SHA256", namespaces=NS): errs.append("SHA256 nesakrīt ar avota datni") pos, missing = 0, [] for e in r.iter(): if not isinstance(e.tag, str): continue tag = etree.QName(e).localname if tag in ("Text", "Note", "LegalBasis", "Lead", "Line", "Heading") or (tag == "Title" and etree.QName(e.getparent()).localname != "Act"): for part in (e.text or "").split("\n"): i = body.find(part, pos) if i < 0: missing.append(f"{tag}: {part[:70]}") else: pos = i if e is not r and e.get("id") and not e.get("id").startswith(did + "."): errs.append(f"{e.get('id')} nesākas ar {did}") if tag == "Point" and not e.get("n").endswith(")") and not e.get("id").endswith("." + pid(e.get("n"))): errs.append(f"punkts n={e.get('n')} id={e.get('id')}") errs += [f"nav avotā secībā — {m}" for m in missing[:5]] return errs if __name__ == "__main__": bad = 0 for p in sorted(glob.glob(f"{ROOT}/data/*.xml")): e = check(p) r = etree.parse(p).getroot() pts = len(r.findall(".//n:Point", NS)) print(f"{'OK ' if not e else 'FAIL'} {os.path.basename(p)} punkti {pts}") for x in e: print(" ", x) bad += bool(e) sys.exit(1 if bad else 0)