Sort keys evaluate once per node with the node's own position, size,
variables, and bindings, so position()-based keys work, and NaN keys
order before numbers under data-type=number. Match patterns evaluate
over the matched node's own document, so templates match nodes loaded
through document(); the match cache keys include the document
identity. Xalan baseline 204 -> 187 (sort 18 -> 11, mdocs 14 -> 6).
Templates carry their in-scope xmlns bindings into match patterns
(match cache keyed on pattern plus bindings) and instantiated
expressions, resolving prefixed name tests by namespace URI; with
bindings supplied an unprefixed test selects only the null namespace,
the XPath 1.0 rule. Instruction-scope capture includes the default
declaration: xsl:element honors in-scope xmlns="uri" for unprefixed
names, xmlns="" keeps them namespace-free, and an unusable created
name drops the wrapper, keeping content. Xalan baseline 263 -> 218
(namespace 41 -> 13).
key() and document() read the string value of attribute and namespace
node arguments instead of dropping them, so the Muenchian grouping
idiom works; match patterns evaluate with the XSLT function table,
making key('k','v') and id('x') patterns match; and the XSLT entry
points parse sources, stylesheets, and document() loads with doctypes
allowed, as the conformance corpora require. Xalan baseline
292 -> 263 (idkey 39 -> 16).
apply-templates and for-each keep attribute and namespace nodes in
their selections; the context carries the non-tree current node with
its owner element backing the tree-only machinery, XPath evaluation
and current() start from it, match patterns select attribute nodes
through attribute identities in the match cache, the built-in rules
copy an attribute's or namespace's value as text, xsl:copy copies the
focused attribute or declaration itself, and an attribute result
arriving after element content is ignored (the XSLT recovery).
Sorting, for-each, and choose move to XSLTSorting.swift for the file
caps. Xalan baseline 352 -> 292 (axes 35 -> 16, copy 29 -> 16).
XSLT: template selection resolves each match pattern once per transform via
a per-run MatchCache (the pattern's node set is computed once over the source
tree; selection becomes an identity lookup), replacing per-(node, template)
recompilation and full-tree re-walks. XSD identity validation: a per-run query
cache compiles each selector/field XPath once instead of at every visited
element. Schematron was verified to already store compiled queries. Behavior
unchanged (all suites green); a multi-template shape test over 300 nodes
guards the optimized path. MatchCache lives in its own file to keep the
transformer under the length cap.
Closes#112