Slice 4 of #92. The XSD complex-type and identity-constraint validators move
onto the validation framework, producing located results.
- ComplexValidator threads a coding path through its (inherently recursive)
descent, so every content-model, attribute, and simple-type violation is now
a ValidationError located by path ("... at path: order/qty"). Child steps
carry a sibling index only when a name repeats.
- IdentityValidator returns ValidationError instead of Issue.
- A new XSD rules enum wraps both as Validation<Node, XSDContext> values gated to
the document root, combined by Validator<XSDContext>. XSDContext carries the
type table, the identity constraints, and the root declaration.
- Schema.Document.validate builds the context and runs the validator, returning
[ValidationError].
XSD content-model validation is recursive by nature (a child's type depends on
its position), so the rules delegate to the recursion while contributing to one
error collection. Schematron is the last validator on Issue and migrates next.
Extend the schema parser toward full structural parity:
- list simple types validate each whitespace-separated item against the item
type and count items for the length facets; union simple types admit a value
valid for any member type. A restriction over a named list or union inherits
its variety.
- Named attribute groups are expanded (transitively) into every complex type
that references them.
- Named model groups are expanded at each xs:group ref, with a cycle guard;
element refs resolve to the referenced global element's declared type,
through a reserved type-table key so forward and recursive refs settle at
validation time.
Named simple types now resolve over repeated passes so they may restrict or
list one another regardless of document order. Simple-type and facet parsing
moves into a sibling XSDSimpleParser to keep each parser within bounds.
Closes#65