Chapter 61. Accessing the contents of XML documents using reader locks

Index

Navigating the XML document using a reader lock
Examining reader lock's current node
Using XPath expressions
#include <x/xml/readlock.H>

auto doc=x::xml::doc::create("filename.xml");

x::xml::readlock rlock=doc->readlock();

A reader lock blocks other threads from modifying the XML document. It blocks the creation of a writer lock. If a writer lock exists, readlock() blocks until the writer lock goes out of scope and gets destroyed. A reader lock does not block other reader locks. Multiple reader locks can exist, and different threads can use other reader locks on the same XML document, but only one thread can use the same reader lock, at the same time.

x::xml::readlock rlock2=rlock->clone();

clone() creates another reader lock by cloning an existing one. A single thread must not call the document's readlock() method to create another reader lock on the same document, the thread must use clone(). This is because readlock(), can be blocked by another thread calling writelock(), a pending writer lock, which is blocked by the first reader lock; this results in a deadlock.

x::xml::readlock is a reference to a reference-counted object. Copying x::xml::readlock variables does not create new reader locks, only more references to the same reader lock get created. Only clone creates a distinct, new, reader lock on the same document.

Navigating the XML document using a reader lock

The contents of an XML document are examined by instantiating a reader lock, then positioning it on different parts of the XML document. Each reader lock is independently positioned. clone() creates a new reader lock which is initially positioned on the same node of the XML document.

bool flag=rlock->get_root();

A new reader lock created by readlock() is not initially positioned on any part of the XML document. get_root() positions the reader lock to the top, root, element of the XML document. get_root() returns false if the x document is empty and does not even have a root node, otherwise a true return indicates that the reader lock is now positioned on the root node.

size_t n=rlock->get_child_element_count();

flag=rlock->get_first_child();

flag=rlock->get_last_child();

flag=rlock->get_next_sibling();

flag=rlock->get_previous_sibling();

flag=rlock->get_parent();

get_child_element_count() returns the number of child node of the reader lock's current node. get_first_child() and get_last_child() reposition the reader lock to the first or the last child node of the reader lock's current node. get_next_sibling() and get_previous_sibling() reposition the reader lock to the next or the previous sibling node. get_parent() repositions the reader lock to the parent node of the reader lock's current node.

These methods return false if the reader lock is not currently positioned on any node, or if the reader lock cannot be repositioned (it does not have any child nodes, or the appropriate sibling node, or if this is the document root node which has no parent node), and the reader lock remains positioned on its current node. Otherwise, the reader lock gets repositioned, and true gets returned.

flag=rlock->get_first_element_child();

flag=rlock->get_last_element_child();

flag=rlock->get_next_element_sibling();

flag=rlock->get_previous_element_sibling();

These methods are similar, except that they ignore all nodes which are node element nodes (like text nodes and comments). get_first_element_child() and get_last_element_child() reposition the reader lock to the first or the last child element node of the reader lock's current node, ignoring any text nodes, comments, or other kind of nodes. get_next_sibling() and get_previous_sibling() reposition the reader lock to the next or the previous sibling element node.

These methods return false if the reader lock is not currently positioned on any node, or if the reader lock cannot be repositioned (it does not have any child nodes which are element nodes, or the appropriate sibling element node.