TXFADataStructure Class
TXFADataStructure, declared in HPDFXFADataStructure, maintains bounded structural edits to an existing native XFA node tree and owns any detached element trees created, cloned, or removed through the graph
CreateDataNode serves Data DOM elements, while CreateElement also supports the model-element construction used by TXFAFormStructure
The constructor borrows Root and validates the existing tree against TXFADataStructureLimits before returning; the graph must be destroyed before the owner of the borrowed root
All public AnsiString names, namespace URIs, and text values contain UTF-8 bytes
Graph := TXFADataStructure.Create(DatasetsRoot, Limits, OnTick);
try
Graph.BeginOperation(OnTick);
try
Node := Graph.CreateDataNode('dataValue', 'amount');
Graph.SetValue(Node, '42');
Graph.Append(RecordNode, Node);
finally
Graph.EndOperation;
end;
finally
Graph.Free;
end;
Operation scope
BeginOperation(OnTick) starts a scope and rejects a nested scope; EndOperation releases the stored callback and is safe during cleanup
The constructor runs its own preflight scope and releases the constructor callback before returning; subsequent methods require a new active scope
OnTick is a Delphi anonymous procedure or an FPC nested procedure of type TXFADataStructureTick; it may raise to cancel work or enforce a caller deadline or operation counter
Methods prepare allocations, ownership capacity, and required namespace declarations before their final cancellation check and structural mutation; a rejected individual edit preserves the existing document graph
A series of successful direct graph calls is not automatically rolled back when a later call fails; the scripting runtime supplies the complete event transaction and restores its document, detached graph, script identities, lexical state, and journal together
Creation and cloning
CreateDataNode(ClassName, Name, NamespaceURI = '') accepts dataGroup or dataValue, creates a fresh detached element, and records explicit data-node class metadata
CreateElement(ClassName, Name, NamespaceURI) creates a detached model element whose XML local name is ClassName, with an optional XFA name attribute and an explicit default namespace declaration
CreateElement validates XML syntax, scalar values, reserved namespace URIs, and graph capacity; the higher-level form factory validates the supported XFA class schema
Name may be an XML local name or a qualified name whose nonempty prefix has the supplied nonempty namespace URI; reserved xml and xmlns bindings are validated
An empty name is permitted for a detached construction step; set a valid name with Rename before attachment
Clone(Node, Recursive = True) creates a detached copy with fresh native identities; a shallow copy keeps the element's own value, attributes, and namespace declarations while excluding child nodes
Inherited namespace declarations are materialized before a clone or move so prefixed attributes retain their original namespace outside their previous ancestor scope
Ownership edits
Append(Parent, Node) moves the same node to the end of the parent's ordered children; InsertBefore(Parent, Node, Before) moves it before an existing direct child, with Before = nil equivalent to append
Remove(Parent, Node) detaches the existing direct child and transfers its ownership to the graph; the object, descendants, and native identities remain valid until graph destruction or detached snapshot restoration
Foreign graphs, cycles, moving the borrowed root, unnamed attachment, invalid sibling references, and node/depth/byte overflow raise EHPDFXFAError
Value and name edits
Rename(Node, Name) changes the element's local XML name while retaining its prefix, namespace URI, position, descendants, and native identity; an attached element requires a nonempty valid XML name
SetValue(Node, Value) validates UTF-8 and XML scalar values, replaces ordinary text children, and preserves comments and processing instructions; empty text removes ordinary text children
SetAttribute(Node, Name, Value) adds or replaces an attribute after validating its qualified-name syntax, UTF-8 value, and projected byte budget; an empty value remains an explicit empty attribute
SetNamespace(Node, NamespaceURI) changes the element's expanded namespace and updates the declaration for its current prefix, while validating reserved bindings
DeclareNamespace(Node, Prefix, NamespaceURI) adds or replaces a namespace declaration without changing the element's expanded name; it rejects a conflicting declaration for the element's own prefix
Direct graph callers coordinate prefixed attributes with their namespace declarations and keep compound edits inside their own rollback transaction
The byte and node budgets include the element's aggregate value and its actual owned text node, rather than charging only one representation of the text
XML import preflight
ValidateImport(Node, Incoming, Overwrite, OnTick) checks the projected aggregate graph before a caller imports an owned list of incoming XML children
When Overwrite is true, the projected size excludes the target's replaced children and aggregate value; otherwise existing children remain in the budget
The method leaves the incoming list and document unchanged and creates a temporary operation scope only when no scope is already active
Detached snapshots
CaptureDetached returns a value snapshot of every detached root and descendant, including text, CDATA, comments, processing instructions, attributes, and namespace declarations
RestoreDetached(Snapshot) validates and prepares a replacement detached forest before swapping ownership; its returned node array follows the snapshot order and contains fresh native identities for caller remapping
See TXFADataStructureSnapshot for record fields and identity rules
Inspection
Root exposes the borrowed root and DetachedRoots exposes the graph-owned roots for inspection; use graph methods for changes so ownership and budgets remain coherent
Transactional Data DOM scripting · Transactional form tree scripting · TXFANode