The two monolithic XSD content/identity rules only satisfied the OpenAPIKit
validation idiom at the wrong granularity: no per-constraint removability,
no isolable failing/near-miss tests. Split them into 32 named rules, each
finding tagged at its origin and cached per XSDContext so the walk still
runs once per document (the #101 decision against duplicating XSD's
recursive type resolution still holds). Wired the streaming path's ID/IDREF
and identity checks through the same framework instead of calling the
validators imperatively, and added the unwrapAndLookup combinator the rule
already named as required.
Also includes the mandated repo-wide swiftformat/swiftlint pass.
Close the last superficially-located checker (#169): referenceFindings was
dispatched as located but its body wrapped the whole aggregate in
.unlocated, so every reference-resolution error still collapsed onto the
schema root. Convert all six sub-collectors to located findings, each
attaching to the node in scope: the core type/base/itemType/memberTypes/ref/
substitutionGroup walk and the xs:-namespace builtin check locate on the
referencing element; the simpleContent base-kind check on the restriction;
the un-imported-namespace check on the referencing element; the
redefine-component-existence check on the redefine's child component; and
the import-namespace-agreement check on the import element.
Every predicate, aggregation order, and reason string is unchanged; only the
location each finding carries differs, verified conformance-neutral by the
full XSTS suite (14383 groups, pinned counts unchanged). Removes two dead
helpers exposed along the way: the unused referenceErrors [String] wrapper
and the unused locatedFindings helper in SchemaCompileValidation. The outer
aggregation is rewritten from a single + chain to incremental appends to keep
the type-checker within budget. Adds a located-diagnostics test per
node-locatable sub-collector; the loader-dependent redefine/import families
are exercised by the XSTS suite.
On the cross-document skip path (a schema declares import/include/redefine
but no external document was loaded), the reference check stood down whole,
so a prefixed reference whose namespace is never imported was accepted even
though it can resolve to no component under any loading (corpus schZ011's
d:d, where namespaces a/b/c are imported but d is not).
Add undeclaredNamespaceReferenceErrors, run only on that skip path, to flag
a reference whose namespace is neither the target, the XSD or XML namespace,
nor named by any xs:import. To stay sound when the import closure is unknown,
it stands down entirely the moment any external carries a schemaLocation:
that document may transitively import the referenced namespace (corpus
schZ004 imports only a, yet a's document imports b, so b:b resolves). It
applies only when every external is location-less and the closure is
provably complete.
XSTS invalid-schemas-accepted 43 -> 39 (schZ011_a-d); valid-schemas-rejected
held at 0; no other bucket moved.