Parses, queries and updates XML document structures.
The XML class creates and maintains parsed XML data as a hierarchy of XTag structures. It accepts both strictly well-formed XML and the module's default relaxed parsing mode, depending on the Flags supplied by the caller. Parsed documents can be queried with XPath/XQuery expressions, modified with XML methods and validated against an XML Schema loaded with LoadSchema().
XML data can be loaded from a file path, from an in-memory XML statement or from another object that supports the Read action. Set Path to load from the file system, Statement to parse an XML string, or Source to read from another object. When Path or Statement is changed after initialisation, the object clears the previous document and parses the new source.
Parsed content is available through Tags. Each XTag stores the element name, attributes, child tags, content nodes, line number and namespace ID. C++ callers can traverse the hierarchy directly through kt::vector<XTag>; Tiri callers should cache Tags only while the XML object remains unchanged because reading the field copies the structure.
Use the XML object's methods when changing the tree so that modification timestamps and derived state remain consistent. Direct read access to XTag is appropriate for traversal and high-volume inspection.
Not supported: DTD validation is not implemented. The parser records DOCTYPE declarations and selected entity, notation and identifier data, but it does not load or validate external DTDs. Use XML Schema (XSD) validation instead.
The XML class consists of the following fields:
Access | Name | Type | Comment | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| DocType | STRING | Root element name from a parsed DOCTYPE declaration. | |||||||||||||||||||||||||||||||||||||||||||
| ErrorMsg | STRING | A textual description of the last parse error. | |||||||||||||||||||||||||||||||||||||||||||
This field may provide a textual description of the last parse error that occurred, in conjunction with the most recently received error code. Issues parsing malformed XPath expressions may also be reported here. | |||||||||||||||||||||||||||||||||||||||||||||
| Flags | XMF | Controls XML parsing behaviour and processing options. | |||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
| Modified | INT | A timestamp of when the XML data was last modified. | |||||||||||||||||||||||||||||||||||||||||||
The Modified field provides an artificial timestamp value of when the XML data was last modified (e.g. by a tag insert or update). Storing the current Modified value and making comparisons later makes it easy to determine that a change has been made. A rough idea of the total number of change requests can also be calculated by subtracting out the difference. | |||||||||||||||||||||||||||||||||||||||||||||
| Path | STRING | Set this field if the XML document originates from a file source. | |||||||||||||||||||||||||||||||||||||||||||
XML documents can be loaded from the file system by specifying a file path in this field. If set post-initialisation, all currently loaded data will be cleared and the file will be parsed automatically. The XML class supports LoadFile(), so an XML file can be pre-cached by the program if it is frequently used during a program's life cycle. In the case where a Statement has been defined, setting the Path with a folder reference may be necessary to establish the base path for relative references in XQuery statements (e.g. for importing XQuery modules). | |||||||||||||||||||||||||||||||||||||||||||||
| PublicID | STRING | Public identifier from a parsed DOCTYPE declaration. | |||||||||||||||||||||||||||||||||||||||||||
| Source | OBJECTPTR | Set this field if the XML data is to be sourced from another object. | |||||||||||||||||||||||||||||||||||||||||||
An XML document can be loaded from another object by referencing it here, on the condition that the object's class supports the Read action. If set post-initialisation, all currently loaded data will be cleared and the source object will be parsed automatically. | |||||||||||||||||||||||||||||||||||||||||||||
| Statement | STRING | XML data is processed through this field. | |||||||||||||||||||||||||||||||||||||||||||
Set the Statement field to parse an XML formatted data string through the object. If this field is set after initialisation then the XML object will clear any existing data first. Be aware that setting this field with an invalid statement will result in an empty XML object. Reading the Statement field returns a serialised string of XML data. By default, all tags are included in the statement. The string result is an allocation that must be freed by the caller. If the statement is an XQuery expression with base-uri references, the Path field should be set to establish the base path for relative references. | |||||||||||||||||||||||||||||||||||||||||||||
| SystemID | STRING | System identifier from a parsed DOCTYPE declaration. | |||||||||||||||||||||||||||||||||||||||||||
| Tags | XTag[] | Provides direct access to the XML document structure. | |||||||||||||||||||||||||||||||||||||||||||
The Tags field exposes the complete XML document structure as a hierarchical array of XTag structures. This field becomes available after successful XML parsing and provides the primary interface for reading XML content programmatically. Each XTag will have at least one attribute set in the Direct read access to the Tags hierarchy is safe and efficient for traversing the document structure. However, modifications should be performed using the XML object's methods (InsertXML(), SetAttrib(), RemoveTag(), etc.) to maintain internal consistency and trigger appropriate cache invalidation. NOTE: Tiri will copy this field on read, caching the value is therefore recommended. | |||||||||||||||||||||||||||||||||||||||||||||
The following actions are currently supported:
| Clear | Completely clears all XML data and resets the object to its initial state. | |||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ERR acClear(*Object) The Clear action removes parsed XML content, namespace base URI mappings, DOCTYPE information, entity data, notation data and parser status. The object remains usable and can receive new XML data afterwards. Error Codes
| ||||||||||||||||||||||||
| DataFeed | Processes and integrates external XML data into the object's document structure. | |||||||||||||||||||||||
ERR acDataFeed(*Object, OBJECTID Object, DATA Datatype, std::span<const int8_t> Buffer)
DataFeed accepts XML or text data and parses it into the object's tag hierarchy. If the object has no existing tags, the parsed data becomes the document structure. If tags already exist, the new data is parsed into a temporary hierarchy and appended to the root-level tag list. The action is rejected when Example:
local xml = obj.new('xml')
local err = xml.acDataFeed(nil, DATA_XML, 'First element')
Error Codes
| ||||||||||||||||||||||||
| Reset | Clears the information held in an XML object. | |||||||||||||||||||||||
| SaveToObject | Saves XML data to a storage object (e.g. File), optionally using another format encoder. | |||||||||||||||||||||||
ERR acSaveToObject(*Object, OBJECTID Dest, CLASSID ClassID)
Set | ||||||||||||||||||||||||
| SetKey | Sets attributes and content in the XML tree using XPaths. | |||||||||||||||||||||||
ERR acSetKey(*Object, std::string_view Key, std::string_view Value)
Use SetKey to add tag attributes and content using XPaths. The XPath is specified in the It is not possible to add new tags using this action - it is only possible to update existing tags. Please note that making changes to the XML tree will render all previously obtained tag pointers and indexes invalid. Error Codes
| ||||||||||||||||||||||||
The following methods are currently supported:
| Evaluate | Run an XQuery expression against the XML data. | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ERR xml::Evaluate(OBJECTPTR Object, STRVIEW Statement, STRING * Result)
The Evaluate method allows the execution of XPath 2.0+ and XQuery 1.0+ expressions against the data contained within the XML object. This is a lazy execution method that compiles and evaluates the provided expression in a single step, returning the result as a string. For more complex scenarios or repeated evaluations, consider using the Compile and Evaluate functions in the XPath module. Error Codes
| |||||||||||||||||||||||||||||||||||||
| Filter | Filters the XML data structure to retain only a specific tag and its descendants. | ||||||||||||||||||||||||||||||||||||
ERR xml::Filter(OBJECTPTR Object, STRVIEW XPath)
The Filter method provides a mechanism for reducing large XML documents to a specific subtree, permanently removing all content that exists outside the targeted element and its children. This operation is particularly valuable for performance optimisation when working with large documents where only a specific section is relevant. The filtering process locates the first element matched by the supplied XPath/XQuery expression. The XML object is then replaced by a new root-level structure containing that tag and its descendants. Sibling tags, parent elements and unrelated branches are discarded. Error Codes
| |||||||||||||||||||||||||||||||||||||
| GetAttrib | Retrieves the value of a specific XML attribute from a tagged element. | ||||||||||||||||||||||||||||||||||||
ERR xml::GetAttrib(OBJECTPTR Object, INT Index, STRVIEW Attrib, STRING * Value)
The GetAttrib method provides efficient access to individual attribute values within XML elements. Given a tag identifier and attribute name, the method performs a case-insensitive search through the element's attribute collection and returns the corresponding value. When a specific attribute name is provided, the method searches through all attributes of the target tag. The search is case-insensitive to accommodate XML documents with varying capitalisation conventions. When the attribute name is empty, the method returns the tag name itself, providing convenient access to element names without requiring separate API calls. For applications requiring frequent attribute access or high-performance scenarios, C++ developers should consider direct access to the XMLAttrib structure array. This bypasses the method call overhead and provides immediate access to all attributes simultaneously. The method performs a linear search through the attribute collection, so performance scales with the number of attributes per element. For elements with many attributes, caching frequently accessed values may improve performance. Error Codes
| |||||||||||||||||||||||||||||||||||||
| GetContent | Extracts the immediate text content of an XML element, excluding nested tags. | ||||||||||||||||||||||||||||||||||||
ERR xml::GetContent(OBJECTPTR Object, INT Index, STRING * Buffer)
The GetContent method extracts only the immediate content-node children of the specified element. Text contained inside nested elements is not included. Consider the following XML structure: <body> Hello <bold>emphasis</bold> world! </body> The GetContent method would extract For scenarios requiring serialised XML rather than immediate text content, use Serialise(). To inspect nested text content, traverse the child XTag hierarchy directly. It is recommended that C++ programs bypass this method and access the XMLAttrib structure directly. Error Codes
| |||||||||||||||||||||||||||||||||||||
| GetEntity | Retrieves the value of a parsed entity declaration. | ||||||||||||||||||||||||||||||||||||
ERR xml::GetEntity(OBJECTPTR Object, STRVIEW Name, STRING * Value)
This method returns the expanded value associated with a general entity parsed from the document's DOCTYPE declaration. Entity names are case-sensitive and must match exactly as declared. Error Codes
| |||||||||||||||||||||||||||||||||||||
| GetNamespaceURI | Retrieve the namespace URI for a given namespace UID. | ||||||||||||||||||||||||||||||||||||
ERR xml::GetNamespaceURI(OBJECTPTR Object, UINT NamespaceID, STRING * Result)
This method retrieves the original namespace URI string for a given namespace UID. Error Codes
| |||||||||||||||||||||||||||||||||||||
| GetNotation | Retrieves information about a parsed notation declaration. | ||||||||||||||||||||||||||||||||||||
ERR xml::GetNotation(OBJECTPTR Object, STRVIEW Name, STRING * Value)
Returns the system or public identifier captured for a notation declaration inside the document type definition. If both public and system identifiers were provided they are returned as a single string separated by a single space. Error Codes
| |||||||||||||||||||||||||||||||||||||
| GetTag | Returns a pointer to the XTag structure for a given tag index. | ||||||||||||||||||||||||||||||||||||
ERR xml::GetTag(OBJECTPTR Object, INT Index, struct XTag ** Result)
This method will return the XTag structure for a given tag Error Codes
| |||||||||||||||||||||||||||||||||||||
| InsertContent | Inserts text content into the XML document structure at specified positions. | ||||||||||||||||||||||||||||||||||||
ERR xml::InsertContent(OBJECTPTR Object, INT Index, XMI Where, STRVIEW Content, INT * Result)
The InsertContent method will insert content strings into any position within the XML tree. A content string must be provided in the To modify existing content, call SetAttrib() instead. Error Codes
| |||||||||||||||||||||||||||||||||||||
| InsertXML | Parse an XML string and insert it in the XML tree. | ||||||||||||||||||||||||||||||||||||
ERR xml::InsertXML(OBJECTPTR Object, INT Index, XMI Where, STRVIEW XML, INT * Result)
The InsertXML() method is used to translate and insert a new set of XML tags into any position within the XML tree. A standard XML statement must be provided in the XML parameter and the target insertion point is specified in the Index parameter. An insertion point relative to the target index must be specified in the Error Codes
| |||||||||||||||||||||||||||||||||||||
| InsertXPath | Inserts an XML statement in an XML tree. | ||||||||||||||||||||||||||||||||||||
ERR xml::InsertXPath(OBJECTPTR Object, STRVIEW XPath, XMI Where, STRVIEW XML, INT * Result)
The InsertXPath method is used to translate and insert a new set of XML tags into any position within the XML tree. A standard XML statement must be provided in the XML parameter and the target insertion point is referenced as a valid Error Codes
| |||||||||||||||||||||||||||||||||||||
| LoadSchema | Load an XML Schema definition to enable schema-aware validation. | ||||||||||||||||||||||||||||||||||||
ERR xml::LoadSchema(OBJECTPTR Object, STRVIEW Path)
This method parses an XML Schema document and attaches its schema context to the current XML object. Once loaded, schema metadata is available for validation and XQuery evaluation routines that utilise schema-aware behaviour. Error Codes
| |||||||||||||||||||||||||||||||||||||
| MoveTags | Move an XML tag group to a new position in the XML tree. | ||||||||||||||||||||||||||||||||||||
ERR xml::MoveTags(OBJECTPTR Object, INT Index, INT Total, INT DestIndex, XMI Where)
This method is used to move XML tags within the XML tree structure. It supports the movement of single and groups of tags from one index to another. The client must supply the index of the tag that will be moved and the index of the target tag. All child tags of the source will be included in the move. An insertion point relative to the target index must be specified in the Error Codes
| |||||||||||||||||||||||||||||||||||||
| RegisterNamespace | Register a namespace URI and return its UID. | ||||||||||||||||||||||||||||||||||||
ERR xml::RegisterNamespace(OBJECTPTR Object, STRVIEW URI, UINT * Result)
This method registers a namespace URI and returns a UID that can be used to identify the namespace efficiently throughout the XML document. Error Codes
| |||||||||||||||||||||||||||||||||||||
| RemoveTag | Removes tag(s) from the XML structure. | ||||||||||||||||||||||||||||||||||||
ERR xml::RemoveTag(OBJECTPTR Object, INT Index, INT Total)
The RemoveTag method is used to remove one or more tags from an XML structure. Child tags will automatically be discarded as a consequence of using this method, in order to maintain a valid XML structure. This method can delete multiple sibling tags when the Note: Removing tags will destabilise all cached address pointers that have been acquired from the XML object. Error Codes
| |||||||||||||||||||||||||||||||||||||
| RemoveXPath | Removes tag(s) from the XML structure using an XPath lookup. | ||||||||||||||||||||||||||||||||||||
ERR xml::RemoveXPath(OBJECTPTR Object, STRVIEW XPath, INT Limit)
The RemoveXPath method is used to remove one or more tags from an XML structure. Child tags will automatically be discarded as a consequence of using this method, in order to maintain a valid XML structure. Individual tag attributes can also be removed if an attribute is referenced at the end of the The removal routine is repeated until no further match is found or the This method is volatile and will destabilise any cached address pointers that have been acquired from the XML object. Error Codes
| |||||||||||||||||||||||||||||||||||||
| ResolvePrefix | Resolve a namespace prefix to the UID of its namespace URI within a tag's scope. | ||||||||||||||||||||||||||||||||||||
ERR xml::ResolvePrefix(OBJECTPTR Object, STRVIEW Prefix, INT TagID, UINT * Result)
This method resolves a namespace prefix to its corresponding namespace URI hash by examining namespace declarations within the specified tag's hierarchical scope. The resolution process:
This approach correctly handles nested namespace scopes and prefix redefinitions. Error Codes
| |||||||||||||||||||||||||||||||||||||
| Search | Searches for XML elements using XPath and XQuery expressions with optional callback processing. | ||||||||||||||||||||||||||||||||||||
ERR xml::Search(OBJECTPTR Object, STRVIEW Expression, FUNCTION Callback, INT * Result)
The Search method provides the primary mechanism for locating XML elements within the document structure using XPath and XQuery expressions. The method supports both single-result queries and comprehensive tree traversal with callback-based processing for complex operations. When no callback function is provided, Search returns the first matching element and terminates the search immediately. This is optimal for simple queries where only the first occurrence is required. When a callback function is specified, Search calls it for each matching element until the query completes, the callback returns an error, or the callback returns The C++ prototype for Callback is The callback should return Note: If an error occurs, check the ErrorMsg field for a custom error message containing further details. Error Codes
| |||||||||||||||||||||||||||||||||||||
| Serialise | Serialise part of the XML tree to an XML string. | ||||||||||||||||||||||||||||||||||||
ERR xml::Serialise(OBJECTPTR Object, INT Index, XMF Flags, STRING * Result)
The Serialise() method will serialise all or part of the XML data tree to a string. The string will be copied into the caller-provided Result parameter. Error Codes
| |||||||||||||||||||||||||||||||||||||
| SetAttrib | Adds, updates and removes XML attributes. | ||||||||||||||||||||||||||||||||||||
ERR xml::SetAttrib(OBJECTPTR Object, INT Index, XMS Attrib, STRVIEW Name, STRVIEW Value)
This method updates existing XML tag attributes, creates new attributes and clears content. The data for the attribute is defined in the NOTE: The attribute at position 0 declares the name of the tag and should not normally be accompanied with a value declaration. However, if the tag represents content within its parent, then the Name must be left empty and the Error Codes
| |||||||||||||||||||||||||||||||||||||
| SetTagNamespace | Set the namespace for a specific XML tag. | ||||||||||||||||||||||||||||||||||||
ERR xml::SetTagNamespace(OBJECTPTR Object, INT TagID, INT NamespaceID)
This method assigns a namespace to an XML tag using the namespace's UID. Error Codes
| |||||||||||||||||||||||||||||||||||||
| Sort | Sorts XML tags to your specifications. | ||||||||||||||||||||||||||||||||||||
ERR xml::Sort(OBJECTPTR Object, STRVIEW XPath, STRVIEW Sort, XSF Flags)
The Sort method is used to sort a single branch of XML tags in ascending or descending order. An The Error Codes
| |||||||||||||||||||||||||||||||||||||
| ValidateDocument | Validate the XML document against the currently loaded schema. | ||||||||||||||||||||||||||||||||||||
ERR xml::ValidateDocument(OBJECTPTR Object) This method performs structural and simple type validation of the document using the loaded XML Schema. It returns Error Codes
| |||||||||||||||||||||||||||||||||||||
Standard flags for the XML class.
| Name | Description |
|---|---|
| XMF::HAS_SCHEMA | Automatically defined when a schema has been loaded into the XML object. |
| XMF::INCLUDE_COMMENTS | By default, comments are stripped when parsing XML input unless this flag is specified. |
| XMF::INCLUDE_SIBLINGS | Include siblings when building an XML string (GetXMLString() only) |
| XMF::INCLUDE_WHITESPACE | By default the XML parser will skip content between tags when they contain pure whitespace. Setting this flag will retain all whitespace. |
| XMF::INDENT | Indent the output of serialised XML to improve readability. |
| XMF::LOCK_REMOVE | Prevents removal of tags from the XML tree. This specifically affects the RemoveTag and RemoveXPath methods. |
| XMF::LOG_ALL | Print extra log messages. |
| XMF::NAMESPACE_AWARE | Enable namespace processing during parsing. |
| XMF::NEW | Creates an empty XML object on initialisation - if the Path field has been set, the source file will not be loaded. |
| XMF::NO_ESCAPE | Turns off escape code conversion. |
| XMF::OMIT_TAGS | Prevents tags from being output when the XML is serialised (output content only). |
| XMF::PARSE_ENTITY | Enables parsing of DOCTYPE entities. |
| XMF::PARSE_HTML | Automatically parse HTML escape codes. |
| XMF::READABLE | Indent the output of serialised XML to improve readability. |
| XMF::READ_ONLY | Edits to the document are not permitted. |
| XMF::STANDALONE | Automatically defined when the XML declaration specifies standalone="yes". |
| XMF::STRIP_CDATA | Do not serialise CDATA sections. Note that this option is used as a parameter, not an object flag. |
| XMF::STRIP_CONTENT | Strip all content from incoming XML data. |
| XMF::STRIP_HEADERS | XML headers found in the source data will not be included in the parsed results. |
| XMF::WELL_FORMED | By default, the XML class will accept badly structured XML data. This flag requires that XML statements must be well-formed (tags must balance) or an ERR::BadData error will be returned during processing. |
Tag insertion options.
| Name | Description |
|---|---|
| XMI::CHILD | Insert as the first child of the target. |
| XMI::CHILD_END | Insert as the last child of the target. |
| XMI::NEXT | Insert as the next tag of the target. |
| XMI::PREV | Insert as the previous tag of the target. |
For SetAttrib()
| Name | Description |
|---|---|
| XMS::NEW | Adds a new attribute. Note that if the attribute already exists, this will result in at least two attributes of the same name in the tag. |
| XMS::REMOVE | Removes the named attribute, or clears element content if the name is empty. |
| XMS::UPDATE | As for UPDATE_ONLY, but if the attribute does not exist, it will be created. |
| XMS::UPDATE_ONLY | SetAttrib will find the target attribute and update it. It is not possible to rename the attribute when using this technique. ERR::Search is returned if the attribute cannot be found. |
Options for the Sort method.
| Name | Description |
|---|---|
| XSF::CHECK_SORT | Tells the algorithm to check for a 'sort' attribute in each analysed tag and if found, the algorithm will use that as the sort value instead of that indicated in the Attrib field. |
| XSF::DESC | Sort in descending order. |
Standard flags for XTag.
| Name | Description |
|---|---|
| XTF::CDATA | Tag represents CDATA. |
| XTF::COMMENT | Tag represents a comment of the format <!-- Comment -->. |
| XTF::INSTRUCTION | Tag represents an instruction of the format <?xml?>. |
| XTF::NOTATION | Tag represents a notation of the format <!XML>. |
| Field | Type | Description |
|---|---|---|
| Name | STRING | Name of the attribute |
| Value | STRING | Value of the attribute |
| Field | Type | Description |
|---|---|---|
| ID | INT | Globally unique ID assigned to the tag on creation. |
| ParentID | INT | UID of the parent tag |
| LineNo | INT | Line number on which this tag was encountered |
| Flags | XTF | Optional flags |
| NamespaceID | UINT | Hash of namespace URI or 0 for no namespace |
| Reserved | INT | Private |
| Attribs | kt::vector<XMLAttrib> | Array of attributes for this tag |
| Children | kt::vector<XTag> | Array of child tags |