strlen()
function executed on the same data. rapidxml.hpp
file to a convenient place (such as your project directory), and include it where needed. You may also want to use printing functions contained in header rapidxml_print.hpp
.<cassert>
, <cstdlib>
, <new>
and <exception>
, unless exceptions are disabled). It should compile on any reasonably conformant compiler, and was tested on Visual C++ 2003, Visual C++ 2005, Visual C++ 2008, gcc 3, gcc 4, and Comeau 4.3.3. Care was taken that no warnings are produced on these compilers, even with highest warning levels enabled.wchar_t
strings containing UTF-16 or UTF-32 if endianness of the data matches that of the machine. UTF-8 is fully supported, including all numeric character references, which are expanded into appropriate UTF-8 byte sequences (unless you enable parse_no_utf8 flag). ' & " < > &#...;
Other character references are not expanded.new
operator would be far too slow. Underlying memory allocations performed by the pool can be customized by use of memory_pool::set_allocator() function. See class memory_pool for more information.rapidxml_utils.hpp
and rapidxml_print.hpp
. Contents of these headers is not an essential part of the library, and is currently not documented (otherwise than with comments in code).text
: using namespace rapidxml; xml_document<> doc; // character type defaults to char doc.parse<0>(text); // 0 means default parse flags
doc
object is now a root of DOM tree containing representation of the parsed XML. Because all RapidXml interface is contained inside namespace rapidxml
, users must either bring contents of this namespace into scope, or fully qualify all the names. Class xml_document represents a root of the DOM hierarchy. By means of public inheritance, it is also an xml_node and a memory_pool. Template parameter of xml_document::parse() function is used to specify parsing flags, with which you can fine-tune behaviour of the parser. Note that flags must be a compile-time constant.cout << "Name of my first node is: " << doc.first_node()->name() << "\n"; xml_node<> *node = doc.first_node("foobar"); cout << "Node foobar has value " << node->value() << "\n"; for (xml_attribute<> *attr = node->first_attribute(); attr; attr = attr->next_attribute()) { cout << "Node foobar has attribute " << attr->name() << " "; cout << "with value " << attr->value() << "\n"; }
xml_document<> doc; xml_node<> *node = doc.allocate_node(node_element, "a", "Google"); doc.append_node(node); xml_attribute<> *attr = doc.allocate_attribute("href", "google.com"); node->append_attribute(attr);One quirk is that nodes and attributes do not own the text of their names and values. This is because normally they only store pointers to the source text. So, when assigning a new name or value to the node, care must be taken to ensure proper lifetime of the string. The easiest way to achieve it is to allocate the string from the xml_document memory pool. In the above example this is not necessary, because we are only assigning character constants. But the code below uses memory_pool::allocate_string() function to allocate node name (which will have the same lifetime as the document), and assigns it to a new node:
xml_document<> doc; char *node_name = doc.allocate_string(name); // Allocate string and copy name into it xml_node<> *node = doc.allocate_node(node_element, node_name); // Set node name to node_nameCheck Reference section for description of the entire interface.
xml_document
and xml_node
objects into an XML string. Use print() function or operator <<, which are defined in rapidxml_print.hpp
header. using namespace rapidxml; xml_document<> doc; // character type defaults to char // ... some code to fill the document // Print to stream using operator << std::cout << doc; // Print to stream using print function, specifying printing flags print(std::cout, doc, 0); // 0 means default printing flags // Print to string using output iterator std::string s; print(std::back_inserter(s), doc, 0); // Print to memory buffer using output iterator char buffer[4096]; // You are responsible for making the buffer large enough! char *end = print(buffer, doc, 0); // end contains pointer to character after last printed character *end = 0; // Add string terminator after XML
strlen()
function executed on the same data. On a modern CPU (as of 2007), you can expect parsing throughput to be close to 1 GB/s. As a rule of thumb, parsing speed is about 50-100x faster than Xerces DOM, 30-60x faster than TinyXml, 3-12x faster than pugxml, and about 5% - 30% faster than pugixml, the fastest XML parser I know of.new
operator, but also their lifetime will be tied to the lifetime of document, possibly simplyfing memory management. free()
function -- all allocations are freed at once when clear() function is called, or when the pool is destroyed. RAPIDXML_STATIC_POOL_SIZE
bytes of statically allocated memory. Until static memory is exhausted, no dynamic memory allocations are done. When static memory is exhausted, pool allocates additional blocks of memory of size RAPIDXML_DYNAMIC_POOL_SIZE
each, by using global new[]
and delete[]
operators. This behaviour can be changed by setting custom allocation routines. Use set_allocator() function to set them. RAPIDXML_ALIGNMENT
bytes. This value defaults to the size of pointer on target architecture. RAPIDXML_STATIC_POOL_SIZE
, RAPIDXML_DYNAMIC_POOL_SIZE
and RAPIDXML_ALIGNMENT
to obtain best wasted memory to performance compromise. To do it, define their values before rapidxml.hpp file is included. memory_pool();
~memory_pool();
xml_node<Ch>* allocate_node(node_type type, const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0);
std::bad_alloc
. If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function will call rapidxml::parse_error_handler() function. xml_attribute<Ch>* allocate_attribute(const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0);
std::bad_alloc
. If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function will call rapidxml::parse_error_handler() function. Ch* allocate_string(const Ch *source=0, std::size_t size=0);
std::bad_alloc
. If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function will call rapidxml::parse_error_handler() function. xml_node<Ch>* clone_node(const xml_node< Ch > *source, xml_node< Ch > *result=0);
void clear();
void set_allocator(alloc_func *af, free_func *ff);
longjmp()
function to pass control to other place of program. If it returns invalid pointer, results are undefined.
void *allocate(std::size_t size);
void free(void *pointer);
std::exception
class. parse_error(const char *what, void *where);
virtual const char* what() const;
Ch* where() const;
xml_attribute();
xml_document<Ch>* document() const;
xml_attribute<Ch>* previous_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;
xml_attribute<Ch>* next_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;
xml_base();
Ch* name() const;
std::size_t name_size() const;
Ch* value() const;
std::size_t value_size() const;
void name(const Ch *name, std::size_t size);
void name(const Ch *name);
void value(const Ch *value, std::size_t size);
void value(const Ch *value);
xml_node<Ch>* parent() const;
xml_document();
void parse(Ch *text);
void clear();
xml_node(node_type type);
node_type type() const;
xml_document<Ch>* document() const;
xml_node<Ch>* first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;
xml_node<Ch>* last_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;
xml_node<Ch>* previous_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;
xml_node<Ch>* next_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;
xml_attribute<Ch>* first_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;
xml_attribute<Ch>* last_attribute(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const;
void type(node_type type);
void prepend_node(xml_node< Ch > *child);
void append_node(xml_node< Ch > *child);
void insert_node(xml_node< Ch > *where, xml_node< Ch > *child);
void remove_first_node();
void remove_last_node();
void remove_node(xml_node< Ch > *where);
void remove_all_nodes();
void prepend_attribute(xml_attribute< Ch > *attribute);
void append_attribute(xml_attribute< Ch > *attribute);
void insert_attribute(xml_attribute< Ch > *where, xml_attribute< Ch > *attribute);
void remove_first_attribute();
void remove_last_attribute();
void remove_attribute(xml_attribute< Ch > *where);
void remove_all_attributes();
void rapidxml::parse_error_handler(const char *what, void *where);
OutIt rapidxml::print(OutIt out, const xml_node< Ch > &node, int flags=0);
std::basic_ostream<Ch>& rapidxml::print(std::basic_ostream< Ch > &out, const xml_node< Ch > &node, int flags=0);
std::basic_ostream<Ch>& rapidxml::operator<<(std::basic_ostream< Ch > &out, const xml_node< Ch > &node);
const int parse_no_data_nodes
= 0x1;
const int parse_no_element_values
= 0x2;
const int parse_no_string_terminators
= 0x4;
const int parse_no_entity_translation
= 0x8;
const int parse_no_utf8
= 0x10;
const int parse_declaration_node
= 0x20;
const int parse_comment_nodes
= 0x40;
const int parse_doctype_node
= 0x80;
const int parse_pi_nodes
= 0x100;
const int parse_validate_closing_tags
= 0x200;
const int parse_trim_whitespace
= 0x400;
const int parse_normalize_whitespace
= 0x800;
const int parse_default
= 0;
const int parse_non_destructive
= parse_no_string_terminators | parse_no_entity_translation;
const int parse_fastest
= parse_non_destructive | parse_no_data_nodes;
const int parse_full
= parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags;
const int print_no_indenting
= 0x1;