Pugixml
Table of Contents
This is some frequently used APIs and functionalities I used. For a complete reference, refer to http://pugixml.org.
1 load
1.1 parse result
struct xml_parse_result { xml_parse_status status; ptrdiff_t offset; xml_encoding encoding; operator bool() const; const char* description() const; };
xmlparsestatus
- statusok
- statusfilenotfound
- …
1.2 parse options
The usual bitwise arithmetics: `mask | flag` and `mask & ~flag`.
- parsetrimpcdata: off. if the leading and trailing whitespace are to be removed.
- parsewspcdata: off. if PCDATA nodes that consist only of whitespace are to be sustained.
- parseminimal: all options turned off
- parsedefault
- parsefull
1.3 Load
1.3.1 from file
API:
xml_parse_result xml_document::load_file( const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto );
example
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file("tree.xml");
1.3.2 from memory
API:
// immutable buffer xml_parse_result xml_document::load_buffer( const void* contents, size_t size, unsigned int options = parse_default, xml_encoding = encoding_auto ); // equivalent with call load_buffer with size strlen(contents) // null terminated string xml_parse_result xml_document::load_string( const char_t* contents, unsigned int options = parse_default );
examples:
const char source[] = "<hello>world</hello>"; size_t size = sizeof(source); pugi::xml_parse_result result = doc.load_buffer(source, size); pugi::xml_parse_result result = doc.load_string("<hello>world</hello>");
1.3.3 from IO streams
API:
xml_parse_result xml_document::load( std::istream& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto );
example:
std::ifstream stream("a.xml");
pugi::xml_parse_result result = doc.load(stream);
2 read
if some node doesn't have name or value, the function will return "".
node:
const char_t* xml_node::name() const; const char_t* xml_node::value() const; // value of the first child with type node_pcdata or node_cdata const char_t* xml_node::child_value() const; // wrapper for child(name).child_value() const char_t* xml_node::child_value(const char_t* name) const;
attr:
const char_t* xml_attribute::name() const; const char_t* xml_attribute::value() const; // as_xx int xml_attribute::as_int(int def = 0) const; unsigned int xml_attribute::as_uint(unsigned int def = 0) const; double xml_attribute::as_double(double def = 0) const; float ... bool ... long long ... unsigned long long ...
xmltext:
xml_text xml_node::text() const; xml_node xml_text::data() const;
if the node is `nodepcdata` or `nodecdata`, return the node's data. else, return the first child node of `nodepcdata` or `nodecdata`.
API:
bool xml_text::empty() const; // equal to text.data().value() const char_t* xml_text::get() const; bool xml_text::set(const char_t* rhs);
asxx:
const char_t* xml_text::as_string(const char_t* def = "") const; int xml_text::as_int(int def = 0) const; unsigned int xml_text::as_uint(unsigned int def = 0) const; double xml_text::as_double(double def = 0) const; float xml_text::as_float(float def = 0) const; bool xml_text::as_bool(bool def = false) const; long long xml_text::as_llong(long long def = 0) const; unsigned long long xml_text::as_ullong(unsigned long long def = 0) const;
bool xml_text::set(int rhs); bool xml_text::set(unsigned int rhs); bool xml_text::set(double rhs); bool xml_text::set(float rhs); bool xml_text::set(bool rhs); bool xml_text::set(long long rhs); bool xml_text::set(unsigned long long rhs); xml_text& xml_text::operator=(const char_t* rhs); xml_text& xml_text::operator=(int rhs); xml_text& xml_text::operator=(unsigned int rhs); xml_text& xml_text::operator=(double rhs); xml_text& xml_text::operator=(float rhs); xml_text& xml_text::operator=(bool rhs); xml_text& xml_text::operator=(long long rhs); xml_text& xml_text::operator=(unsigned long long rhs);
3 modify
3.1 set
bool xml_node::set_name(const char_t* rhs); bool xml_node::set_value(const char_t* rhs); bool xml_attribute::set_name(const char_t* rhs); bool xml_attribute::set_value(const char_t* rhs);
attribute can use different type other than string:
bool xml_attribute::set_value(int rhs); bool xml_attribute::set_value(unsigned int rhs); bool xml_attribute::set_value(double rhs); bool xml_attribute::set_value(float rhs); bool xml_attribute::set_value(bool rhs); bool xml_attribute::set_value(long long rhs); bool xml_attribute::set_value(unsigned long long rhs); xml_attribute& xml_attribute::operator=(const char_t* rhs); xml_attribute& xml_attribute::operator=(int rhs); xml_attribute& xml_attribute::operator=(unsigned int rhs); xml_attribute& xml_attribute::operator=(double rhs); xml_attribute& xml_attribute::operator=(float rhs); xml_attribute& xml_attribute::operator=(bool rhs); xml_attribute& xml_attribute::operator=(long long rhs); xml_attribute& xml_attribute::operator=(unsigned long long rhs);
3.2 add/remove
node:
xml_node xml_node::append_child(xml_node_type type = node_element); xml_node xml_node::prepend_child(xml_node_type type = node_element); xml_node xml_node::insert_child_after(xml_node_type type, const xml_node& node); xml_node xml_node::insert_child_before(xml_node_type type, const xml_node& node); // node_element with tagname name xml_node xml_node::append_child(const char_t* name); xml_node xml_node::prepend_child(const char_t* name); xml_node xml_node::insert_child_after(const char_t* name, const xml_node& node); xml_node xml_node::insert_child_before(const char_t* name, const xml_node& node);
attr:
xml_attribute xml_node::append_attribute(const char_t* name); xml_attribute xml_node::prepend_attribute(const char_t* name); xml_attribute xml_node::insert_attribute_after(const char_t* name, const xml_attribute& attr); xml_attribute xml_node::insert_attribute_before(const char_t* name, const xml_attribute& attr);
remove:
bool xml_node::remove_attribute(const xml_attribute& a); bool xml_node::remove_attribute(const char_t* name); bool xml_node::remove_child(const xml_node& n); bool xml_node::remove_child(const char_t* name);
example:
// delete all nodes with specified name while (node.remove_child("tool"));
more examples:
node.append_attribute("type").set_value("1"); node.append_child(pugi::node_pcdata).set_value("Content");
3.3 clone
node:
xml_node xml_node::append_copy(const xml_node& proto); xml_node xml_node::prepend_copy(const xml_node& proto); xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node); xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node);
attr:
xml_attribute xml_node::append_copy(const xml_attribute& proto); xml_attribute xml_node::prepend_copy(const xml_attribute& proto); xml_attribute xml_node::insert_copy_after( const xml_attribute& proto, const xml_attribute& attr ); xml_attribute xml_node::insert_copy_before( const xml_attribute& proto, const xml_attribute& attr );
3.4 move node
copy the node and remove the origin. But this is expensive. The following API avoid that.
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);
4 traversal
node:
xml_node xml_node::parent() const; xml_node xml_node::first_child() const; xml_node xml_node::last_child() const; xml_node xml_node::next_sibling() const; xml_node xml_node::previous_sibling() const; xml_node xml_node::root() const; // tag name xml_node xml_node::child(const char_t* name) const; xml_node xml_node::next_sibling(const char_t* name) const; xml_node xml_node::previous_sibling(const char_t* name) const; // find by attr xml_node xml_node::find_child_by_attribute( const char_t* name, const char_t* attr_name, const char_t* attr_value ); xml_node xml_node::find_child_by_attribute( const char_t* attr_name, const char_t* attr_value );
attr:
xml_attribute xml_node::first_attribute() const; xml_attribute xml_node::last_attribute() const; xml_attribute xml_attribute::next_attribute() const; xml_attribute xml_attribute::previous_attribute() const; // tag name xml_attribute xml_node::attribute(const char_t* name) const;
Attributes do not have a link to their parent nodes because of memory consumption reasons.
4.1 range based loop(C++11)
implementation-defined-type xml_node::children() const; implementation-defined-type xml_node::children(const char_t* name) const; implementaiton-defined-type xml_node::attributes() const;
example
for (pugi::xml_node tool : tools.children("Tool")) { // ... }
4.2 iterators
API:
class xml_node_iterator; class xml_attribute_iterator; typedef xml_node_iterator xml_node::iterator; iterator xml_node::begin() const; iterator xml_node::end() const; typedef xml_attribute_iterator xml_node::attribute_iterator; attribute_iterator xml_node::attributes_begin() const; attribute_iterator xml_node::attributes_end() const;
example
for (pugi::xml_node_iterator it=tools.begin();it!=tools.end();it++) { // it->xxx }
4.3 xmltreewalker
API:
class xml_tree_walker { public: virtual bool begin(xml_node& node); virtual bool for_each(xml_node& node) = 0; virtual bool end(xml_node& node); int depth() const; }; bool xml_node::traverse(xml_tree_walker& walker);
- `begin` is called with root
- `foreach` is called for all nodes in Depth First Order, except root.
- `end` is called with root
if `begin`, `end`, or any of `foreach` return false, the traversal terminates and return false.
example
struct simple_walker : pugi::xml_tree_walker { virtual bool for_each(pugi::xml_node& node) { // node return true; // continue } }; simple_walker walker; doc.traverse(walker);
4.4 simple path
string_t xml_node::path(char_t delimiter = '/') const; xml_node xml_node::first_element_by_path( const char_t* path, char_t delimiter = '/' );
path can be relative or absolute(start with delimiter).
5 xpath
5.1 types
`xpathnode` can be either a node or an attribute.
xml_node xpath_node::node() const; xml_attribute xpath_node::attribute() const; xml_node xpath_node::parent() const;
`xpathnodeset`
xpath_node xpath_node_set::first() const; const xpath_node& xpath_node_set::operator[](size_t index) const; size_t xpath_node_set::size() const; bool xpath_node_set::empty() const;
5.2 query
// equal to select_nodes().first() xpath_node xml_node::select_node( const char_t* query, xpath_variable_set* variables = 0 ) const; xpath_node_set xml_node::select_nodes( const char_t* query, xpath_variable_set* variables = 0 ) const; // precompiled version xpath_node xml_node::select_node(const xpath_query& query) const; xpath_node_set xml_node::select_nodes(const xpath_query& query) const;
5.2.1 precompiled query
constructor:
explicit xpath_query::xpath_query( const char_t* query, xpath_variable_set* variables = 0 );
API:
bool xpath_query::evaluate_boolean(const xpath_node& n) const; double xpath_query::evaluate_number(const xpath_node& n) const; string_t xpath_query::evaluate_string(const xpath_node& n) const; // equal to node.select_nodes() xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const; // equal to node.select_node() xpath_node xpath_query::evaluate_node(const xpath_node& n) const;