Creating new XML elements and attributes

auto doc=x::xml::doc::create();

x::xml::writelock wlock=doc->writelock();

wlock->create_child()->element({"html"});

A creator's element() method creates a new XML element node. Its parameter is an instance of a helper class, x::new_element, which has several different constructors that provide alternate ways of defining the new element, and it's convenient to invoke them using braced initializer lists, as in this example.

A braced initializer list or a constructor with one string creates a new element in an unnamed namespace. This example creates <html>.

element(), and all other creator factory elements, return a reference to the same creator class:

wlock->create_child()->element({"html"})->element({"body"});

The first call to element() creates an <html> XML element. The create_child() creator factory installs the new element as the child element of the writer lock's current node, then repositions the writer lock to the new <html> XML element. The second call to element() creates a new <body> XML element. Because the writer lock is now positioned on the <html> XML element, the new element becomes its child node.

creator->element({"prefix:item"});

This example creates a new item element node in the prefix namespace, which must be an XML namespace that's opened in the new element's parent node, or one of its parents.

creator->element({"item", "http://www.example.com"});

The two argument form of the constructor to the x::xml::new_element helper class, the argument to element() creates a new element in an XML namespace whose URI is given by the second argument, that's specified either as a literal string or a x::uriimpl. This namespace must be opened in the new element's parent node, or one of its parents.

creator->element({"item", "itemlist", "http://www.example.com"});

The three argument form of the constructor creates a new element in a new namespace that gets opened in the new element itself. The second argument gives the namespace prefix, the third argument gives the new namespace's URI. The above example creates, basically, <itemlist:item xmlns:itemlist="http://www.example.com">. create_namespace() adds a namespace to the the writer lock's current element:

creator->element({"item", "itemlist", "http://www.example.com"})
       ->create_namespace("packages", "http://www.example.com/packages");

This example results in a new <itemlist:item xmlns:itemlist="http://www.example.com" xmlns:packages="http://www.example.com/packages"> child node. create_namespace(), for convenience, can be invoked as either a creator or as a writer lock method:

wlock->create_child()->element({"item", "itemlist", "http://www.example.com"})
       ->create_namespace("packages", "http://www.example.com/packages");

and

wlock->create_child()->element({"item", "itemlist", "http://www.example.com"});
wlock->create_namespace("packages", "http://www.example.com/packages");

have the same results. create_namespace() simply creates and opens a new namespace in the XML element the writer lock is currently positioned to, and create_child() positions the writer lock to the new element.

Similarly, attribute() creates a new attribute in the XML element the writer lock is currently positioned to:

creator->attribute({"style", "white-space: nowrap"})
       ->attribute({"class", "address"});

The writer lock must be positioned on an element node in the document; attribute() adds a new attribute to the element.

The parameter to attribute() is also an internal helper class, x::xml::new_attribute which has several different constructors, and gets typically given literally using a braced initializer list, for convenience. The first example's initializer is a single string, which initializes a new attribute named style, in an unnamed namespace with the value of white-space: nowrap.

wlock->attribute({"html:style", "white-space: nowrap"});

This version of attribute()'s initializer adds a new attribute in a namespace with the given prefix that must be open in its element, or one of its parent elements.

wlock->attribute({"style", "http://www.w3.org/1999/xhtml", "white-space: nowrap"});

This version of attribute()'s initializer adds a new attribute in a namespace with the given URI, that must be open in its element, or one of its parent elements. The URI can be given as a literal string, or as an x::uriimpl.

creator->element({"html:div"},
                        {
	                    {"style", "white-space: nowrap"},
	                    {"id", "box"}
	                }
                   );

The two parameter version of element() creates a new element, and all of its attributes, in one go. The first parameter is still the same internal helper class, x::xml::doc::base::newelement, that can be given literally as a braced literally using a braced initializer list.

The second parameter is a std::vector that enumerates the new element's attributes, as x::xml::doc::base::newattribute helper class instances. This also can be expressed as a braced initializer list. The above example creates an x element node div, in the html namespace, with two attributes, style and id.

The two parameter version of element() is equivalent to calling the one parameter version, passing it the first parameter, then calling attribute() repeatedly, passing it each element in the second parameter's vector.