Index
#include <x/xml/writelock> auto doc=x::xml::doc::create(); x::xml::doc::base::writelock wlock=doc->writelock();
A writer lock
blocks all other reader
and writer locks.
It blocks the creation of all other locks.
If any other lock exists, writelock
() blocks until
all other locks go out of scope and gets destroyed.
x::xml::writelock
is a reference to a reference-counted
object. Copying x::xml::doc::base::writelock
variables
does not create new writer locks, only more references to the same
writer lock get created. The writer lock object is a subclass
of a reader lock, and implements all reader
lock methods, except for clone
().
Only one writer lock can exist at a time. Invoking a writer lock's
clone
() method throws an exception.
Creating new elements in an XML document is a two-step process:
Invoke either the writer lock's
create_child
(),
create_next_sibling
(), or the
create_previous_sibling
() method.
These methods return a
x::xml::createnode
, or a
“creator factory”,
which is a reference to a
reference-counted
object with several methods that create a new element, comment,
a processing instruction, or some other
part of an XML document.
create_child
()'s methods add the new element
as a child element of the current node.
Invoking
create_next_sibling
()'s or
create_previous_sibling
()'s method adds
the new element as the corresponding sibling element of the
writer lock's current node.
Before invoking a creator factory's method, the writer lock should be positioned,
using the methods that it inherits from the
reader lock, to the appropriate
existing element in the XML document. Afterwards,
invoking one of creator factory's
methods creates a new XML node, and installs it
with respect to the writer lock's current node. As a special case,
a new writer lock in a new, empty document, is not positioned on any
existing node. If a writer lock is not positioned on any node, its
create_child
()'s methods installs the
document's root node.
In all cases, after creating and installing a new XML node, the
writer lock is repositioned so that its current node is the new XML
node. Invoking another (or the same) creator factory method creates
another new
XML node. The second new XML node gets installed again, by the
creator factory, with respect to the first XML node. So, for example,
using create_child
()'s creator factory installs
the first new node as a child node of the original XML parent node,
and invoking one of creator factory's methods again installs the second
new node as a child node of the first new node, since the first new node
became the writer lock's current node.
The creator factory holds a reference on the writer lock, until the last reference to the creator factory goes out of scope, and it gets destroyed.
The creator factory is not bound to any particular part of the XML
document, it is bound to a writer lock (on which it holds an internal
reference), and the writer lock is positioned on some existing
element of the XML document. The writer lock uses the same methods
as a reader lock (it inherits them), to change its current position.
It is not necessary to destroy a creator factory, then recreate it
after reposition the writer lock. If it's the same creator factory type
(create_child
(),
create_next_sibling
(), or
create_previous_sibling
()), it's quite
usable after repositioning the writer lock, and will continue to
perform its duties, with respect to the writer lock's new position.
wlock->create_child()->element({"p"}) ->create_next_sibling()->element({"p"}) ->parent()->element({"p"});
This example calls a writer lock's create_child
()
factory. The writer lock is presumed to be already positioned on an
existing XML element node. The creator factory's
element
()
creates a new “<p>
” node, and the
creator factory installs this as a new child element, then repositions
the writer lock to the new element.
element
() returns a reference to the same
creator factory, and at this point, invoking
element
() would create a second XML element,
and install it as <p>
's child element, because
it's now the writer lock's current element.
For convenience, each creator factory also implements its origin
writer lock's
create_child
(),
create_next_sibling
(), and
create_previous_sibling
() methods,
that return the other types of creator factories. This allows a single
statement to create new XML nodes in different “directions”.
The above example switches to the
create_next_sibling
() creator factory and
installs another
<p>
element as its sibling. The net effect is
the creation of
two <p>
elements from the parent node.
For convenience, each creator factory also implements
parent
()
by repositioning the writer lock to its current node's parent node.
After creating these two new <p>
child elements
of of the parent
node, the writer lock gets positioned on the second child element.
parent
() repositions the writer lock to the
original parent node.
The creator factory remains unchanged, it's still
create_next_sibling
(), and a third call to
element
() creates
a sibling element of the original parent node.