Commit Graph

11 Commits

Author SHA1 Message Date
cfba3ed7d2 feat(html): lenient HTML parser and serializer
Add the PureXML.HTML namespace: a lenient tokenizer for tag-soup input
(case-insensitive tags; quoted, unquoted, and boolean attributes; comments;
doctype; character references), a tree builder handling void elements,
optional end tags (li, p, table rows and cells), raw-text elements (script,
style), and unmatched end tags, and a serializer that writes void elements
unclosed and raw-text content unescaped.

Closes #36
Closes #37
Closes #38
Closes #39
Closes #20
2026-06-08 07:12:42 +02:00
96eb85f1fc feat(xslt): stylesheet model and parser
Add the PureXML.XSLT namespace with a stylesheet model (template rules with
match patterns and computed default priorities, the instruction sequence
constructor, attribute value templates) and a parser compiling an
xsl:stylesheet document into it. Recognizes the XSLT vocabulary by namespace
or xsl prefix; other elements become literal result elements. Covers
apply-templates, value-of, for-each, if, choose, element, attribute, copy,
copy-of, call-template, variable, text, and sort.

Closes #14
2026-06-08 06:57:11 +02:00
e862f364aa feat(schema): XSD simple-type datatype library with facets
Add the PureXML.Schema namespace validating XSD Part 2 built-in datatypes
and constraining facets. Built-ins span string/boolean/decimal, the bounded
integer family with intrinsic bounds, float/double, duration, the eight
date/time types, hexBinary, base64Binary, anyURI, QName, and the
Name/NCName/NMTOKEN/language family. Facets: length/minLength/maxLength,
pattern (via the regex engine), enumeration (value-space comparison),
whiteSpace, min/maxInclusive/Exclusive, totalDigits, fractionDigits.
Decimals compare exactly with no floating-point loss; date/time fields are
range-validated with leap years, 24:00:00, and timezone bounds.

Closes #8
2026-06-08 06:29:37 +02:00
951b808f02 feat(regex): XML Schema regular-expression engine
Add the PureXML.Regex namespace: a recursive-descent parser for the XSD
regex grammar (literals, ., character classes with ranges and negation, the
\d \w \s family and negations, single-char escapes, grouping, alternation,
and the ?, *, +, {n}, {n,}, {n,m} quantifiers) compiled to a Thompson NFA.
matches(_:) is whole-string as xs:pattern requires, and runs linear in the
input with no backtracking blow-up. \p{...} category escapes are not yet
supported.

Closes #59
Closes #60
Closes #30
2026-06-08 06:18:50 +02:00
a9be5253cf feat(canonical): Canonical XML (C14N) serialization
Add the PureXML.Canonical namespace rendering the C14N form: namespaces
sorted by prefix (default first), attributes by namespace URI then local
name, empty elements expanded to start/end pairs, CDATA folded into escaped
text, and the C14N escaping rules. Inclusive mode renders every in-scope
namespace; exclusive mode renders only visibly-used namespaces plus an
InclusiveNamespaces prefix list. Comments omitted unless requested. For
whole-tree canonicalization C14N 1.0 and 1.1 coincide.

Closes #54
Closes #55
Closes #56
Closes #26
2026-06-08 06:13:02 +02:00
85f2ad2ebd feat(xinclude): XInclude, URI resolution, and xml:base
Add the PureXML.XInclude namespace: RFC 3986 reference resolution
(URIReference with dot-segment removal) and an xi:include processor over the
value tree. href resolves against the base and in-scope xml:base; parse=xml
includes the document element or an xpointer() fragment (via PureXML.XPointer),
parse=text includes raw text, and a failed load uses xi:fallback or errors.
Includes nest. No I/O is done internally: fetching is only through the
injected loadingURI closure, so the default fetches nothing.

Closes #48
Closes #49
Closes #50
Closes #51
Closes #24
2026-06-08 06:08:31 +02:00
634270d529 feat(catalog): OASIS XML Catalog resolution
Add the PureXML.Catalog namespace: parse an OASIS XML catalog (public,
system, uri, rewriteSystem, rewriteURI, group/catalog by local name) into a
Resolver mapping public/system identifiers and URI names to URIs, with
longest-prefix rewriting and system-over-public precedence. entityResolver
(loadingURI:) builds a Parsing.EntityResolver that resolves an external
identifier through the catalog and loads the URI via an injected closure, so
a catalog plus loader wires entities and DTDs in while the default keeps XXE
closed.

Closes #57
Closes #58
Closes #27
2026-06-08 06:03:02 +02:00
627c035c2a feat(xpointer): element() and xpointer() schemes
Add the PureXML.XPointer namespace resolving the shorthand bare-name form
(id), the element() scheme (child-element positions from an id or the
document root), and the xpointer() scheme (a full XPath expression). Scheme
parts chain with the XPointer fallback rule: the first non-empty selection
wins. element() data is translated to the equivalent XPath and evaluated by
PureXML.XPath, so no separate evaluator is needed.

Closes #46
Closes #47
Closes #23
2026-06-08 05:52:23 +02:00
f7fe89023c feat(pattern): streaming xmlPattern matching
Add the PureXML.Pattern namespace: a compiler for the streamable XPath
subset (names, *, prefix:*, /, //, leading absolute /, trailing @attr) into
a Matcher, with predicates and . / .. rejected. The backward-matching
algorithm tests an element's ancestor-or-self path. Pattern.matches(_:in:)
streams a document through the pull parser and returns matching node paths
in document order from the open-element stack alone, no tree built.

Closes #44
Closes #45
Closes #22
2026-06-08 05:49:13 +02:00
1ae6680d94 feat(xpath): add an XPath 1.0 location-path subset
Add PureXML.XPath: a compiled location-path query engine reimplemented from the
XPath 1.0 specification; no upstream code copied.

- Compiler parses a path into steps; Evaluator walks the tree returning a
  Selection node-set (node or attribute) in document order.
- Forward axes only (child, descendant //, self ., attribute @), since the value
  model has no parent pointers. Node tests: name, *, text(), node(), comment().
  Predicates: [n], [@a], [@a='v'], [child], [child='v'].
- Public surface: XPath.Query (init compiles, evaluate/elements/strings), the
  Selection enum (element / stringValue), QueryError, and the one-shot
  PureXML.xpath(_:over:). Upward/sibling axes and the full expression language
  are explicitly out of scope.
- 12 XPath tests; 61 total.
2026-06-08 01:32:23 +02:00
708390242c chore: scaffold PureXML pure-Swift XML package
Root Swift package mirroring PureYAML's structure, rules, and verification
gates. Includes the XML node model (Node, Element, Attribute, QualifiedName),
a working emitter (Serializer) with escaping and pretty/compact options, and
structural validation. The parser surface is stable; parse() raises
notImplemented until the scanner lands, pinned by a test.

- dependency-free, namespaced under PureXML
- portability and style gates carried over (style, namespacing, forbidden
  patterns, swiftformat, swiftlint, linux, wasm, windows CI)
- 11 tests passing
2026-06-07 23:20:20 +02:00