MIRA
XML

Contents

What is the XMLDom class

The XMLDom class is an STL-conforming wrapper around the libxml2 library that is published under the MIT-License. It provides iterator-based access to the content of XML documents, using the DOM interface. In a nutshell, DOM (Document Object Model) means that navigation between the nodes of a XML document is allowed as well as editing, inserting and deleting nodes. Therefore, documents managed by the XMLDom class will be read from file or memory as a whole document. Large XML documents where data is stored in an ordered way are better to be accessed via a SAX reader.

Reading and writing documents

XML documents can be read from file or from a memory buffer using loadFromFile() or loadFromString(). XML documents can be written to file or memory using saveToFile() or saveToString().

Navigating through XML documents

Each XML document has a root node. The root node can be accessed by root(). For navigating through the document, you can use iterators. Each node is either an const_sibling_iterator or an sibling_iterator. Calling the function begin() of a node returns an iterator to the first child node. end() returns the end iterator.

// Printing the names of all child nodes of the root node
XMLDom::sibling_iterator i = doc.root().begin();
for ( ; i!=doc.root().end(); ++i)
std::cout << "The name of the node is " << *i << std::endl;

The iterator-based concept allows to use STL algorithms such as std::find:

XMLDom::sibling_iterator i = std::find(doc.root().begin(), doc.root().end(), "MyNodeName");

The begin method optionally supports a node name to allow iterating over child nodes with the same name:

// Printing the content of all child nodes with name "Child" of the root node
XMLDom::sibling_iterator i = doc.root().begin("Child");
for ( ; i!=doc.root().end(); ++i)
std::cout << "The content of the node is " << *i.content_begin() << std::endl;

You can also navigate back in the XML tree by calling parent() on an iterator to get the iterator to its parent node.

Each node may have attributes that also support iterators via attribute_begin() and attribute_end(). The (value, name) pair of the attribute can be accessed using the dereferencing operator on the attribute_iterator.

XMLDom::attribute_iterator atIter = iter.attribute_begin();
XMLDom::Attribute attr = *atIter;
std::cout << attr.first << " = " << attr.second;

Alternatively you can call name() or value() on the iterator to get access to the name or value of the attribute. It is also possible to get the typed value of an attribute directly:

int i;
if ( node.find_attribute("MyIntAttribute") != node.attribute_end() )
i = node.get_attribute<int>("MyIntAttribute");

Without the if in the example you could get an XInvalidConfig exception when no such attribute exists. You can also provide default values for these cases.

int i = node.get_attribute<int>("MyIntAttribute",10);

Like for the attributes, iterators are the way to access content and comments of nodes. content_begin() returns the iterator to the first content where comment_begin() returns the iterator to the first comment.

Creating documents

For the creation of XML documents, only iterators can be used. The iterator supports adding and inserting children, adding attributes and content as well as comments via the functions add_child(), insert_before(), insert_after(), add_attribute(), add_comment() and add_content().

Creating documents is easy because these functions return an iterator again and can therefore be chained together.

XMLDom doc;
XMLDom::sibling_iterator node = doc.root().
add_child("Node").
add_attribute("StringAttribute", "text").
add_comment("This is a comment").
add_content("This is content").
add_child("SubNode").
add_attribute("IntAttribute", 1).
add_comment("This is a comment").
add_content("This is content");
doc.saveToFile("test.xml");
// creates the following document
<Root>
<Node StringAttribute="text">
<!-- This is a comment -->
This is content
<SubNode IntAttribute="1">
<!-- This is a comment -->
This is content
</SubNode>
</Node>
</Root>

Modifying documents

Only iterators allow modification of XML documents. You can use remove() to remove nodes from the document or replace() to replace a node by another.