From 1a06d7d3de3d2f30eaf3d56b7b2d0fa3446d46d8 Mon Sep 17 00:00:00 2001
From: Arseny Kapoulkine
The document in pugixml is fully mutable: you can completely change the document
@@ -61,12 +62,11 @@
- As discussed
- before, nodes can have name and value, both of which are strings. Depending
- on node type, name or value may be absent. node_document
+
+ As discussed before, nodes can have name and value, both of which are strings.
+ Depending on node type, name or value may be absent. node_document
nodes do not have a name or value, node_element
and node_declaration nodes always
have a name but never have a value, node_pcdata,
@@ -98,31 +98,31 @@
This is an example of setting node name and value (samples/modify_base.cpp):
+
- All
- attributes have name and value, both of which are strings (value may be empty).
- You can set them with the following functions:
+
+ All attributes have name and value, both of which are strings (value may
+ be empty). You can set them with the following functions:
- For convenience, all
+ For convenience, all
-
-pugixml 1.4 manual |
+pugixml 1.5 manual |
Overview |
Installation |
Document:
@@ -28,16 +28,17 @@
-
pugi::xml_node node = doc.child("node");
-// change node name
-std::cout << node.set_name("notnode");
+// change node name
+std::cout << node.set_name("notnode");
std::cout << ", new node name: " << node.name() << std::endl;
-// change comment text
-std::cout << doc.last_child().set_value("useless comment");
+// change comment text
+std::cout << doc.last_child().set_value("useless comment");
std::cout << ", new comment text: " << doc.last_child().value() << std::endl;
-// we can't change value of the element or name of the comment
-std::cout << node.set_value("1") << ", " << doc.last_child().set_name("2") << std::endl;
+// we can't change value of the element or name of the comment
+std::cout << node.set_value("1") << ", " << doc.last_child().set_name("2") << std::endl;
bool xml_attribute::set_name(const char_t* rhs);
bool xml_attribute::set_value(const char_t* rhs);
@@ -177,8 +177,8 @@
including string conversions.
set_value
+set_value
functions have the corresponding assignment operators:
xml_attribute& xml_attribute::operator=(const char_t* rhs);
@@ -199,19 +199,20 @@
This is an example of setting attribute name and value (samples/modify_base.cpp):
+
pugi::xml_attribute attr = node.attribute("id"); -// change attribute name/value -std::cout << attr.set_name("key") << ", " << attr.set_value("345"); +// change attribute name/value +std::cout << attr.set_name("key") << ", " << attr.set_value("345"); std::cout << ", new attribute: " << attr.name() << "=" << attr.value() << std::endl; -// we can use numbers or booleans -attr.set_value(1.234); +// we can use numbers or booleans +attr.set_value(1.234); std::cout << "new attribute value: " << attr.value() << std::endl; -// we can also use assignment operators for more concise code -attr = true; +// we can also use assignment operators for more concise code +attr = true; std::cout << "final attribute value: " << attr.value() << std::endl;
@@ -219,11 +220,10 @@
- Nodes - and attributes do not exist without a document tree, so you can't create +
+ Nodes and attributes do not exist without a document tree, so you can't create them without adding them to some document. A node or attribute can be created at the end of node/attribute list or before/after some other node:
@@ -317,19 +317,20 @@ This is an example of adding new attributes/nodes to the document (samples/modify_add.cpp):+
-// add node with some name -pugi::xml_node node = doc.append_child("node"); +// add node with some name +pugi::xml_node node = doc.append_child("node"); -// add description node with text child -pugi::xml_node descr = node.append_child("description"); +// add description node with text child +pugi::xml_node descr = node.append_child("description"); descr.append_child(pugi::node_pcdata).set_value("Simple node"); -// add param node before the description -pugi::xml_node param = node.insert_child_before("param", descr); +// add param node before the description +pugi::xml_node param = node.insert_child_before("param", descr); -// add attributes to param node -param.append_attribute("name") = "version"; +// add attributes to param node +param.append_attribute("name") = "version"; param.append_attribute("value") = 1.1; param.insert_attribute_after("type", param.attribute("name")) = "float";@@ -338,11 +339,10 @@
- If - you do not want your document to contain some node or attribute, you can +
+ If you do not want your document to contain some node or attribute, you can remove it with one of the following functions:
bool xml_node::remove_attribute(const xml_attribute& a); @@ -394,17 +394,18 @@ This is an example of removing attributes/nodes from the document (samples/modify_remove.cpp):+
-// remove description node with the whole subtree -pugi::xml_node node = doc.child("node"); +// remove description node with the whole subtree +pugi::xml_node node = doc.child("node"); node.remove_child("description"); -// remove id attribute -pugi::xml_node param = node.child("param"); +// remove id attribute +pugi::xml_node param = node.child("param"); param.remove_attribute("value"); -// we can also remove nodes/attributes by handles -pugi::xml_attribute id = param.attribute("name"); +// we can also remove nodes/attributes by handles +pugi::xml_attribute id = param.attribute("name"); param.remove_attribute(id);@@ -412,7 +413,7 @@
pugixml provides a special class, xml_text
,
@@ -421,8 +422,8 @@
documentation for accessing document data; this section describes
the modification interface of xml_text
.
+ Once you have an xml_text
object, you can set the text contents using the following function:
bool xml_text::set(const char_t* rhs); @@ -439,9 +440,9 @@ an element node, this function creates the PCDATA child node if necessary (i.e. if the element node does not have a PCDATA/CDATA child already). -- In addition to a string function, several - functions are provided for handling text with numbers and booleans as contents: +
+ In addition to a string function, several functions are provided for handling + text with numbers and booleans as contents:
bool xml_text::set(int rhs); bool xml_text::set(unsigned int rhs); @@ -457,8 +458,8 @@ functions. You can refer to documentation for the attribute functions for details. -+ For convenience, all
set
functions have the corresponding assignment operators:xml_text& xml_text::operator=(const char_t* rhs); @@ -480,29 +481,30 @@ object to modify text contents (samples/text.cpp):+
-// change project version -project.child("version").text() = 1.2; +// change project version +project.child("version").text() = 1.2; -// add description element and set the contents -// note that we do not have to explicitly add the node_pcdata child -project.append_child("description").text().set("a test project"); +// add description element and set the contents +// note that we do not have to explicitly add the node_pcdata child +project.append_child("description").text().set("a test project");
- With - the help of previously described functions, it is possible to create trees - with any contents and structure, including cloning the existing data. However - since this is an often needed operation, pugixml provides built-in node/attribute - cloning facilities. Since nodes and attributes do not exist without a document - tree, you can't create a standalone copy - you have to immediately insert - it somewhere in the tree. For this, you can use one of the following functions: +
+ With the help of previously described functions, it is possible to create + trees with any contents and structure, including cloning the existing data. + However since this is an often needed operation, pugixml provides built-in + node/attribute cloning facilities. Since nodes and attributes do not exist + without a document tree, you can't create a standalone copy - you have to + immediately insert it somewhere in the tree. For this, you can use one of + the following functions:
xml_attribute xml_node::append_copy(const xml_attribute& proto); xml_attribute xml_node::prepend_copy(const xml_attribute& proto); @@ -559,6 +561,7 @@ node cloning and usage of other document modification functions:+
bool load_preprocess(pugi::xml_document& doc, const char* path); @@ -570,23 +573,23 @@ { pugi::xml_node include = child; - // load new preprocessed document (note: ideally this should handle relative paths) - const char* path = include.value(); + // load new preprocessed document (note: ideally this should handle relative paths) + const char* path = include.value(); pugi::xml_document doc; if (!load_preprocess(doc, path)) return false; - // insert the comment marker above include directive - node.insert_child_before(pugi::node_comment, include).set_value(path); + // insert the comment marker above include directive + node.insert_child_before(pugi::node_comment, include).set_value(path); - // copy the document above the include directive (this retains the original order!) - for (pugi::xml_node ic = doc.first_child(); ic; ic = ic.next_sibling()) + // copy the document above the include directive (this retains the original order!) + for (pugi::xml_node ic = doc.first_child(); ic; ic = ic.next_sibling()) { node.insert_copy_before(ic, include); } - // remove the include node and move to the next child - child = child.next_sibling(); + // remove the include node and move to the next child + child = child.next_sibling(); node.remove_child(include); } @@ -603,8 +606,8 @@ bool load_preprocess(pugi::xml_document& doc, const char* path) { - pugi::xml_parse_result result = doc.load_file(path, pugi::parse_default | pugi::parse_pi); // for <?include?> - + pugi::xml_parse_result result = doc.load_file(path, pugi::parse_default | pugi::parse_pi); // for <?include?> + return result ? preprocess(doc) : false; }@@ -613,13 +616,64 @@
+ Sometimes instead of cloning a node you need to move an existing node to + a different position in a tree. This can be accomplished by copying the node + and removing the original; however, this is expensive since it results in + a lot of extra operations. For moving nodes within the same document tree, + you can use of the following functions instead: +
+xml_node xml_node::append_move(const xml_node& moved); +xml_node xml_node::prepend_move(const xml_node& moved); +xml_node xml_node::insert_move_after(const xml_node& moved, const xml_node& node); +xml_node xml_node::insert_move_before(const xml_node& moved, const xml_node& node); ++
+ These functions mirror the structure of append_copy
,
+ prepend_copy
, insert_copy_before
and insert_copy_after
+ - they take the handle to the moved object and move it to the appropriate
+ place with all attributes and/or child nodes. The functions return the handle
+ to the resulting object (which is the same as the moved object), or null
+ handle on failure.
+
- pugixml provides several ways to assemble
- an XML document from other XML documents. Assuming there is a set of document
- fragments, represented as in-memory buffers, the implementation choices are
- as follows:
+ The failure conditions resemble those of append_child
,
+ insert_child_before
and related
+ functions, consult their documentation
+ for more information. There are additional caveats specific to moving
+ functions:
+
insert_move_after
and
+ insert_move_before
functions
+ fail if the moved node is the same as the node
+ argument (this operation would be a no-op otherwise).
+ node.append_move(node.parent().parent());
+ will fail.
+ + pugixml provides several ways to assemble an XML document from other XML + documents. Assuming there is a set of document fragments, represented as + in-memory buffers, the implementation choices are as follows:
- Since append_buffer
- needs to append child nodes to the current node, it only works if the current
- node is either document or element node. Calling append_buffer
+
+ Since append_buffer
needs
+ to append child nodes to the current node, it only works if the current node
+ is either document or element node. Calling append_buffer
on a node with any other type results in an error with status_append_invalid_root
status.
-pugixml 1.4 manual | +pugixml 1.5 manual | Overview | Installation | Document: -- cgit v1.2.3 |