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.
Broaden the TextReader pull cursor toward libxml2's xmlTextReader:
- Attribute nodes: moveToFirstAttribute/moveToNextAttribute/
moveToAttribute(_:)/moveToElement reposition the cursor onto each
attribute as an .attribute node and back.
- Namespace accessors: namespaceURI, localName, prefix from the current
element's or attribute's resolved name.
- xml:lang: inherited down the tree, overridable per element, reset when
it goes out of scope.
- Position: lineNumber/columnNumber report where each node begins, so a
streaming consumer can locate findings in the source. EventReader now
records each node's start mark.
DOCTYPE and entity-reference nodes are not surfaced (the DTD is exposed
through documentType, and entities are expanded inline); whitespace is
not split into significant/insignificant (needs the content model);
baseURI needs a document URI. The accurate positioning path for editor
findings remains readTree with source ranges.
Closes#98
Add PureXML.Parsing.TextReader (via PureXML.reader), a pull cursor over the
streaming core. read() advances node by node, exposing nodeKind, name,
value, depth, attributes, and isEmptyElement. A childless element is
reported once as an empty element, normalizing <a/> and <a></a>. The
documentType accessor surfaces the DTD read so far as the validation hook.
Closes#33