PhoenixmlDb.Core
XIncludeProcessor
XInclude 1.0 processor: expands xi:include elements with parse="xml" (structural inclusion) or parse="text" (textual inclusion, SP2) and an href, resolving each reference against the in-scope base URI, recursing into included content, and detecting cyclic / over-deep inclusion.
#XIncludeProcessor
Namespace: PhoenixmlDb.Core.Xml
XInclude 1.0 processor: expands xi:include elements with parse="xml" (structural inclusion) or parse="text" (textual inclusion, SP2) and an href, resolving each reference against the in-scope base URI, recursing into included content, and detecting cyclic / over-deep inclusion.
xpointer / fragid sub-resource selection (SP3) is supported for both an external target (href present, evaluated against the fetched fragment) and a same-document reference (xpointer with no href, evaluated against the master document and guarded against cyclic self-inclusion by containment and bounded by ). The pointer is evaluated via and the selected node-set is spliced in place of the xi:include, with per-element §4.5 xml:base/xml:lang fixup. An empty selection is a fallback-eligible resource error; a selection containing a node that cannot be element content (attribute, document, etc.) is a fatal . parse="text" (SP2) reads the target via — honoring the include's encoding/accept/accept-language attributes — and splices the decoded content in as a single text node in place of the xi:include. A resource error (fetch or decode failure) is fallback-eligible, exactly as for parse="xml"; a fragment identifier in href is still a fatal error (text resources have no fragments). xi:fallback recovery (SP2) IS implemented: a resource error on an xi:include (fetch or parse failure) recovers via a single xi:fallback child's content when present — that content is itself XInclude-processed and replaces the include (an empty fallback simply removes it) — or, absent a fallback, rethrows fatally as before. A misplaced xi:fallback (not a direct child of an xi:include) or more than one on the same xi:include is always a fatal error. xml:base / xml:lang fixup (XInclude 1.0 §4.5): when a top-level included element is spliced into the master, it is stamped with xml:base = the resolved target URI (unless it already carries its own xml:base) and, if it lacks its own xml:lang, with the in-scope xml:lang from the include's ancestor chain (if any). Only the top-level included element is stamped — descendants resolve their base/lang through the added attribute plus their own existing xml:base/xml:lang chain.
#Methods
#AdjustBase(Uri,Xml.XmlElement)
Returns the in-scope base URI for : adjusted by an xml:base attribute on the element itself, if present.
#Expand(Xml.XmlDocument,Uri,PhoenixmlDb.Core.Xml.XIncludeOptions)
Expands every xi:include (parse="xml", href) in , in place, and returns the same mutated document.
Parameters:
-
doc— The document to expand. Mutated in place. -
baseUri— The absolute base URI of , against which relative hrefs (as adjusted by any in-scope xml:base) are resolved. -
options— XInclude processing options (resolver, remote policy, depth).
Returns: The same , with its xi:includes expanded.
is expanded in place. On any thrown it is left partially expanded and in an undefined state and MUST be discarded, not reused. In particular, a same-document xpath1() evaluation that exceeds throws while a background thread may still be reading (System.Xml's XPath engine cannot be cancelled mid-evaluation); discarding the document as required avoids racing that reader.
Exceptions:
-
XIncludeException— Thrown on a malformed xi:include (including a malformed xpointer), a cyclic or over-deep inclusion, a resource-safety limit (), or a resource error with no usable xi:fallback. A resource error that is recovered by an xi:fallback does not throw.
#ExpandNode(Xml.XmlDocument,Xml.XmlNode,Uri,PhoenixmlDb.Core.Xml.XIncludeOptions,PhoenixmlDb.Core.Xml.IXmlResourceResolver,Collections.Generic.List<Uri>,PhoenixmlDb.Core.Xml.XIncludeLimiter)
Depth-first walks 's children in , expanding any xi:include elements. is the in-scope base for itself (already adjusted for the ancestors above it).
#GetInScopeLang(Xml.XmlNode)
Returns the in-scope xml:lang for : the nearest xml:lang declared on itself or an ancestor, or null if none is in scope.
#IsAncestorOrSelf(Xml.XmlNode,Xml.XmlNode)
Returns whether is itself or one of its ancestors (walked via ).
#ProcessSameDocumentXPointer(Xml.XmlDocument,Xml.XmlElement,String,Uri,PhoenixmlDb.Core.Xml.XIncludeOptions,PhoenixmlDb.Core.Xml.IXmlResourceResolver,Collections.Generic.List<Uri>,PhoenixmlDb.Core.Xml.XIncludeLimiter)
Handles an xi:include with an xpointer/fragid and no href: the selection is evaluated against itself (same-document XPointer). A selection that is, or contains, the xi:include element is a fatal (containment-based cyclic guard — the URI-stack guard used for fetched targets doesn't apply here since there is no target URI). Any nested xi:include within the selected subtree is expanded (against the master's own base URI, tracked on the same active stack; remains the runaway backstop) before the copies are spliced in.
#ProcessTextInclude(Xml.XmlDocument,Xml.XmlElement,String,Uri,PhoenixmlDb.Core.Xml.XIncludeOptions,PhoenixmlDb.Core.Xml.IXmlResourceResolver,Collections.Generic.List<Uri>,PhoenixmlDb.Core.Xml.XIncludeLimiter)
Handles an xi:include parse="text": resolves to a text resource via (honoring the encoding/accept/accept-language attributes) and splices its content in as a single text node, replacing the xi:include. A resource error (fetch/decode failure) is fallback-eligible, exactly as for parse="xml".
#RecoverWithFallback(Xml.XmlDocument,Xml.XmlElement,Xml.XmlElement,Uri,PhoenixmlDb.Core.Xml.XIncludeOptions,PhoenixmlDb.Core.Xml.IXmlResourceResolver,Collections.Generic.List<Uri>,Exception,Uri,PhoenixmlDb.Core.Xml.XIncludeLimiter)
Handles a resource error (fetch/parse failure) on an xi:include target: recovers via 's content when present, or rethrows fatally when it is not.
#RunOnLargeStack``1(Func<``0>,String,Int32,String)
Runs on a dedicated worker thread with a large explicit stack (see ), waits up to for it ( = wait forever), and rethrows any exception it produced on the caller's thread with the original stack trace preserved. This is what makes the depth guard — and the xpath1() recursion — bounded by the logical limit rather than the physical thread stack. On timeout the worker is abandoned (System.Xml's XPath engine cannot be cancelled) but, being a background thread on its own large stack, it blocks neither process exit nor the and cannot overflow the caller's stack; a fatal is raised instead.
#SetXmlAttribute(Xml.XmlElement,String,String)
Stamps an attribute in the XML namespace (xml:base/xml:lang) on using the reserved xml prefix. Using with the XML namespace but no prefix leaves the attribute prefix empty, so a later serialization (e.g. via OuterXml) invents a bogus prefix and emits an illegal xmlns:…="http://www.w3.org/XML/1998/namespace" redeclaration; binding the reserved xml prefix here keeps the stamped attribute well-formed on round-trip.
#SpliceNodeSet(Xml.XmlDocument,Xml.XmlElement,Collections.Generic.IReadOnlyList<Xml.XmlNode>,Uri,PhoenixmlDb.Core.Xml.XIncludeLimiter)
Imports each node in into and inserts them, in document order, in place of . Applies XInclude §4.5 xml:base/xml:lang fixup to each top-level included element ( = the origin URI). An attribute (or namespace) node cannot be spliced as content and is a fatal .
#Fields
| Name | Description |
|---|---|
XIncludeNamespace
|
The XInclude 1.0 namespace URI. |