Skip to content
Snippets Groups Projects
pugixml.hpp 70.1 KiB
Newer Older
		PUGIXML_DEPRECATED xml_node next_sibling_w(const char_t* name) const;

		/**
		 * Get following sibling
		 *
		 * \return following sibling node, if any; empty node otherwise
		 */
		xml_node next_sibling() const;

		/**
		 * Get first of preceding sibling nodes with the specified name
		 *
		 * \param name - sibling name
		 * \return node with the specified name, if any; empty node otherwise
		 */
		xml_node previous_sibling(const char_t* name) const;

		/**
		 * Get first of the preceding sibling nodes with the name that matches specified pattern
		 *
		 * \param name - sibling name pattern
		 * \return node with the name that matches pattern, if any; empty node otherwise
		 *
		 * \deprecated This function is deprecated
		PUGIXML_DEPRECATED xml_node previous_sibling_w(const char_t* name) const;

		/**
		 * Get preceding sibling
		 *
		 * \return preceding sibling node, if any; empty node otherwise
		 */
		xml_node previous_sibling() const;

		/**
		 * Get parent node
		 *
		 * \return parent node if any; empty node otherwise
		 */
		xml_node parent() const;

		/**
		 * Get root of DOM tree this node belongs to.
		 *
		 * \return tree root
		 */
		xml_node root() const;

		/**
		 * Get child value of current node; that is, value of the first child node of type PCDATA/CDATA
		 *
		 * \return child value of current node, if any; "" otherwise
		 */
		const char_t* child_value() const;

		/**
		 * Get child value of child with specified name. \see child_value
		 * node.child_value(name) is equivalent to node.child(name).child_value()
		 *
		 * \param name - child name
		 * \return child value of specified child node, if any; "" otherwise
		 */
		const char_t* child_value(const char_t* name) const;

		/**
		 * Get child value of child with name that matches the specified pattern. \see child_value
		 * node.child_value_w(name) is equivalent to node.child_w(name).child_value()
		 *
		 * \param name - child name pattern
		 * \return child value of specified child node, if any; "" otherwise
		 *
		 * \deprecated This function is deprecated
		PUGIXML_DEPRECATED const char_t* child_value_w(const char_t* name) const;

	public:	
		/**
		 * Set node name to \a rhs (for PI/element nodes). \see name
		 *
		 * \param rhs - new node name
		 * \return success flag (call fails if node is of the wrong type or there is not enough memory)
		 */
		bool set_name(const char_t* rhs);
		
		/**
		 * Set node value to \a rhs (for PI/PCDATA/CDATA/comment nodes). \see value
		 *
		 * \param rhs - new node value
		 * \return success flag (call fails if node is of the wrong type or there is not enough memory)
		 */
		bool set_value(const char_t* rhs);

		/**
		 * Add attribute with specified name (for element nodes)
		 *
		 * \param name - attribute name
		 * \return added attribute, or empty attribute if there was an error (wrong node type)
		 */
		xml_attribute append_attribute(const char_t* name);

		/**
		 * Insert attribute with specified name after \a attr (for element nodes)
		 *
		 * \param name - attribute name
		 * \param attr - attribute to insert a new one after
		 * \return inserted attribute, or empty attribute if there was an error (wrong node type, or attr does not belong to node)
		 */
		xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr);

		/**
		 * Insert attribute with specified name before \a attr (for element nodes)
		 *
		 * \param name - attribute name
		 * \param attr - attribute to insert a new one before
		 * \return inserted attribute, or empty attribute if there was an error (wrong node type, or attr does not belong to node)
		 */
		xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr);

		/**
		 * Add a copy of the specified attribute (for element nodes)
		 *
		 * \param proto - attribute prototype which is to be copied
		 * \return inserted attribute, or empty attribute if there was an error (wrong node type)
		 */
		xml_attribute append_copy(const xml_attribute& proto);

		/**
		 * Insert a copy of the specified attribute after \a attr (for element nodes)
		 *
		 * \param proto - attribute prototype which is to be copied
		 * \param attr - attribute to insert a new one after
		 * \return inserted attribute, or empty attribute if there was an error (wrong node type, or attr does not belong to node)
		 */
		xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr);

		/**
		 * Insert a copy of the specified attribute before \a attr (for element nodes)
		 *
		 * \param proto - attribute prototype which is to be copied
		 * \param attr - attribute to insert a new one before
		 * \return inserted attribute, or empty attribute if there was an error (wrong node type, or attr does not belong to node)
		 */
		xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr);

		/**
		 * Add child node with specified type (for element nodes)
		 *
		 * \param type - node type
		 * \return added node, or empty node if there was an error (wrong node type)
		 */
		xml_node append_child(xml_node_type type = node_element);

		/**
		 * Insert child node with specified type after \a node (for element nodes)
		 *
		 * \param type - node type
		 * \param node - node to insert a new one after
		 * \return inserted node, or empty node if there was an error (wrong node type, or \a node is not a child of this node)
		 */
		xml_node insert_child_after(xml_node_type type, const xml_node& node);

		/**
		 * Insert child node with specified type before \a node (for element nodes)
		 *
		 * \param type - node type
		 * \param node - node to insert a new one before
		 * \return inserted node, or empty node if there was an error (wrong node type, or \a node is not a child of this node)
		 */
		xml_node insert_child_before(xml_node_type type, const xml_node& node);

		/**
		 * Add a copy of the specified node as a child (for element nodes)
		 *
		 * \param proto - node prototype which is to be copied
		 * \return inserted node, or empty node if there was an error (wrong node type)
		 */
		xml_node append_copy(const xml_node& proto);

		/**
		 * Insert a copy of the specified node after \a node (for element nodes)
		 *
		 * \param proto - node prototype which is to be copied
		 * \param node - node to insert a new one after
		 * \return inserted node, or empty node if there was an error (wrong node type, or \a node is not a child of this node)
		 */
		xml_node insert_copy_after(const xml_node& proto, const xml_node& node);

		/**
		 * Insert a copy of the specified node before \a node (for element nodes)
		 *
		 * \param proto - node prototype which is to be copied
		 * \param node - node to insert a new one before
		 * \return inserted node, or empty node if there was an error (wrong node type, or \a node is not a child of this node)
		 */
		xml_node insert_copy_before(const xml_node& proto, const xml_node& node);

		/**
		 * Remove specified attribute
		 *
		 * \param a - attribute to be removed
		 */
		void remove_attribute(const xml_attribute& a);

		/**
		 * Remove attribute with the specified name, if any
		 *
		 * \param name - attribute name
		 */
		void remove_attribute(const char_t* name);

		/**
		 * Remove specified child
		 *
		 * \param n - child node to be removed
		 */
		void remove_child(const xml_node& n);

		/**
		 * Remove child with the specified name, if any
		 *
		 * \param name - child name
		 */
		void remove_child(const char_t* name);

	public:
		/**
		 * Get first attribute
		 *
		 * \return first attribute, if any; empty attribute otherwise
		 */
		xml_attribute first_attribute() const;

		/**
		 * Get last attribute
		 *
		 * \return last attribute, if any; empty attribute otherwise
		 */
        xml_attribute last_attribute() const;

		/**
		 * Get all elements from subtree with given name
		 *
		 * \param name - node name
		 * \param it - output iterator (for example, std::back_insert_iterator (result of std::back_inserter))
		 */
		template <typename OutputIterator> void all_elements_by_name(const char_t* name, OutputIterator it) const
		{
			if (!_root) return;
			
			for (xml_node node = first_child(); node; node = node.next_sibling())
			{
				if (node.type() == node_element)
				{
					if (impl::strequal(name, node.name()))
					{
						*it = node;
						++it;
					}
				
					if (node.first_child()) node.all_elements_by_name(name, it);
				}
			}
		}

		/**
		 * Get all elements from subtree with name that matches given pattern
		 *
		 * \param name - node name pattern
		 * \param it - output iterator (for example, std::back_insert_iterator (result of std::back_inserter))
		 *
		 * \deprecated This function is deprecated
		template <typename OutputIterator> PUGIXML_DEPRECATED void all_elements_by_name_w(const char_t* name, OutputIterator it) const
			all_elements_by_name_w_helper(name, it);

		/**
		 * Get first child
		 *
		 * \return first child, if any; empty node otherwise
		 */
		xml_node first_child() const;

		/**
		 * Get last child
		 *
		 * \return last child, if any; empty node otherwise
		 */
        xml_node last_child() const;
		
		/**
		 * Find attribute using predicate
		 *
		 * \param pred - predicate, that takes xml_attribute and returns bool
		 * \return first attribute for which predicate returned true, or empty attribute
		 */
		template <typename Predicate> xml_attribute find_attribute(Predicate pred) const
		{
			if (!_root) return xml_attribute();
			
			for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute())
				if (pred(attrib))
					return attrib;
		
			return xml_attribute();
		}

		/**
		 * Find child node using predicate
		 *
		 * \param pred - predicate, that takes xml_node and returns bool
		 * \return first child node for which predicate returned true, or empty node
		 */
		template <typename Predicate> xml_node find_child(Predicate pred) const
		{
			if (!_root) return xml_node();
	
			for (xml_node node = first_child(); node; node = node.next_sibling())
				if (pred(node))
					return node;
        
	        return xml_node();
		}

		/**
		 * Find node from subtree using predicate
		 *
		 * \param pred - predicate, that takes xml_node and returns bool
		 * \return first node from subtree for which predicate returned true, or empty node
		 */
		template <typename Predicate> xml_node find_node(Predicate pred) const
		{
			if (!_root) return xml_node();

			for (xml_node node = first_child(); node; node = node.next_sibling())
			{
				if (pred(node))
					return node;
				
				if (node.first_child())
				{
					xml_node found = node.find_node(pred);
					if (found) return found;
				}
			}

			return xml_node();
		}

		/**
		 * Find child node with the specified name that has specified attribute
		 *
		 * \param name - child node name
		 * \param attr_name - attribute name of child node
		 * \param attr_value - attribute value of child node
		 * \return first matching child node, or empty node
		 */
		xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;

		/**
		 * Find child node with the specified name that has specified attribute (use pattern matching for node name and attribute name/value)
		 *
		 * \param name - pattern for child node name
		 * \param attr_name - pattern for attribute name of child node
		 * \param attr_value - pattern for attribute value of child node
		 * \return first matching child node, or empty node
		 *
		 * \deprecated This function is deprecated
		PUGIXML_DEPRECATED xml_node find_child_by_attribute_w(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;

		/**
		 * Find child node that has specified attribute
		 *
		 * \param attr_name - attribute name of child node
		 * \param attr_value - attribute value of child node
		 * \return first matching child node, or empty node
		 */
		xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const;

		/**
		 * Find child node that has specified attribute (use pattern matching for attribute name/value)
		 *
		 * \param attr_name - pattern for attribute name of child node
		 * \param attr_value - pattern for attribute value of child node
		 * \return first matching child node, or empty node
		 *
		 * \deprecated This function is deprecated
		PUGIXML_DEPRECATED xml_node find_child_by_attribute_w(const char_t* attr_name, const char_t* attr_value) const;

	#ifndef PUGIXML_NO_STL
		/**
		 * Get the absolute node path from root as a text string.
		 *
		 * \param delimiter - delimiter character to insert between element names
		 * \return path string (e.g. '/bookstore/book/author').
		 */
		string_t path(char_t delimiter = '/') const;
	#endif

		/**
		 * Search for a node by path.
		 * \param path - path string; e.g. './foo/bar' (relative to node), '/foo/bar' (relative 
		 * to root), '../foo/bar'.
		 * \param delimiter - delimiter character to use while tokenizing path
		 * \return matching node, if any; empty node otherwise
		 */
		xml_node first_element_by_path(const char_t* path, char_t delimiter = '/') const;

		/**
		 * Recursively traverse subtree with xml_tree_walker
		 * \see xml_tree_walker::begin
		 * \see xml_tree_walker::for_each
		 * \see xml_tree_walker::end
		 *
		 * \param walker - tree walker to traverse subtree with
		 * \return traversal result
		 */
		bool traverse(xml_tree_walker& walker);
	
	#ifndef PUGIXML_NO_XPATH
		/**
		 * Select single node by evaluating XPath query
		 * 
		 * \param query - query string
		 * \return first node from the resulting node set by document order, or empty node if none found
		 */
		xpath_node select_single_node(const char_t* query) const;

		/**
		 * Select single node by evaluating XPath query
		 *
		 * \param query - compiled query
		 * \return first node from the resulting node set by document order, or empty node if none found
		 */
		xpath_node select_single_node(const xpath_query& query) const;

		/**
		 * Select node set by evaluating XPath query
		 *
		 * \param query - query string
		 * \return resulting node set
		 */
		xpath_node_set select_nodes(const char_t* query) const;

		/**
		 * Select node set by evaluating XPath query
		 *
		 * \param query - compiled query
		 * \return resulting node set
		 */
		xpath_node_set select_nodes(const xpath_query& query) const;
	#endif
		
		/// \internal Document order or 0 if not set
		/// \deprecated This function is deprecated
		PUGIXML_DEPRECATED unsigned int document_order() const;

		/**
		 * Print subtree to writer
		 *
		 * \param writer - writer object
		 * \param indent - indentation string
		 * \param flags - formatting flags
		 * \param encoding - encoding used for writing
		 * \param depth - starting depth (used for indentation)
		 */
		void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, encoding_t encoding = encoding_auto, unsigned int depth = 0) const;

	#ifndef PUGIXML_NO_STL
		/**
		 * Print subtree to stream
		 *
		 * \param os - output stream
		 * \param indent - indentation string
		 * \param flags - formatting flags
		 * \param encoding - encoding used for writing
		 * \param depth - starting depth (used for indentation)
		 */
		void print(std::basic_ostream<char, std::char_traits<char> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, encoding_t encoding = encoding_auto, unsigned int depth = 0) const;

		/**
		 * Print subtree to stream
		 *
		 * \param os - output stream
		 * \param indent - indentation string
		 * \param flags - formatting flags
		 * \param encoding - encoding used for writing
		 * \param depth - starting depth (used for indentation)
		 */
		void print(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const;
	#endif

		/**
		 * Get node offset in parsed file/string (in bytes) for debugging purposes
		 *
		 * \return offset in bytes to start of node data, or -1 in case of error
		 * \note This will return -1 if node information changed to the extent that it's no longer possible to calculate offset, for example
		 * if element node name has significantly changed; this is guaranteed to return correct offset only for nodes that have not changed
		 * since parsing.
		 */
	};

#ifdef __BORLANDC__
	// Borland C++ workaround
	bool PUGIXML_FUNCTION operator&&(const xml_node& lhs, bool rhs);
	bool PUGIXML_FUNCTION operator||(const xml_node& lhs, bool rhs);
#endif

	/**
	 * Child node iterator.
	 * It's a bidirectional iterator with value type 'xml_node'.
	 */
	class PUGIXML_CLASS xml_node_iterator
	{
		friend class xml_node;

	private:
		xml_node _prev;
		xml_node _wrap;

arseny.kapoulkine's avatar
arseny.kapoulkine committed
		/// \internal Initializing constructor
		explicit xml_node_iterator(xml_node_struct* ref);

arseny.kapoulkine's avatar
arseny.kapoulkine committed
		/// \internal Initializing constructor (for past-the-end)
		xml_node_iterator(xml_node_struct* ref, xml_node_struct* prev);

		/**
		 * Iterator traits
		 */
		typedef ptrdiff_t difference_type;
		typedef xml_node value_type;
		typedef xml_node* pointer;
		typedef xml_node& reference;

	#ifndef PUGIXML_NO_STL
		typedef std::bidirectional_iterator_tag iterator_category;
	#endif

arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * Default constructor
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * Initializing constructor
		 *
		 * \param node - node that iterator will point at
		 */
		xml_node_iterator(const xml_node& node);

		/**
		 * Check if this iterator is equal to \a rhs
		 *
		 * \param rhs - other iterator
		 * \return comparison result
		 */
		bool operator==(const xml_node_iterator& rhs) const;
		
		/**
		 * Check if this iterator is not equal to \a rhs
		 *
		 * \param rhs - other iterator
		 * \return comparison result
		 */
		bool operator!=(const xml_node_iterator& rhs) const;

		/**
		 * Dereferencing operator
		 *
		 * \return reference to the node iterator points at
		 */
		xml_node& operator*();

		/**
		 * Member access operator
		 *
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * \return pointer to the node iterator points at
		 */
		xml_node* operator->();

		/**
		 * Pre-increment operator
		 *
		 * \return self
		 */
		const xml_node_iterator& operator++();

		/**
		 * Post-increment operator
		 *
		 * \return old value
		 */
		xml_node_iterator operator++(int);
		
		/**
		 * Pre-decrement operator
		 *
		 * \return self
		 */
		const xml_node_iterator& operator--();
		
		/**
		 * Post-decrement operator
		 *
		 * \return old value
		 */
		xml_node_iterator operator--(int);
	};

	/**
	 * Attribute iterator.
	 * It's a bidirectional iterator with value type 'xml_attribute'.
	 */
	class PUGIXML_CLASS xml_attribute_iterator
	{
		friend class xml_node;

	private:
		xml_attribute _prev;
		xml_attribute _wrap;

arseny.kapoulkine's avatar
arseny.kapoulkine committed
		/// \internal Initializing constructor
		explicit xml_attribute_iterator(xml_attribute_struct* ref);

arseny.kapoulkine's avatar
arseny.kapoulkine committed
		/// \internal Initializing constructor (for past-the-end)
		xml_attribute_iterator(xml_attribute_struct* ref, xml_attribute_struct* prev);

		/**
		 * Iterator traits
		 */
		typedef ptrdiff_t difference_type;
		typedef xml_attribute value_type;
		typedef xml_attribute* pointer;
		typedef xml_attribute& reference;

	#ifndef PUGIXML_NO_STL
		typedef std::bidirectional_iterator_tag iterator_category;
	#endif

arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * Default constructor
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * Initializing constructor
		 *
		 * \param node - node that iterator will point at
		 */
		xml_attribute_iterator(const xml_attribute& node);

		/**
		 * Check if this iterator is equal to \a rhs
		 *
		 * \param rhs - other iterator
		 * \return comparison result
		 */
		bool operator==(const xml_attribute_iterator& rhs) const;
		
		/**
		 * Check if this iterator is not equal to \a rhs
		 *
		 * \param rhs - other iterator
		 * \return comparison result
		 */
		bool operator!=(const xml_attribute_iterator& rhs) const;

		/**
		 * Dereferencing operator
		 *
		 * \return reference to the node iterator points at
		 */
		xml_attribute& operator*();

		/**
		 * Member access operator
		 *
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * \return pointer to the node iterator points at
		 */
		xml_attribute* operator->();

		/**
		 * Pre-increment operator
		 *
		 * \return self
		 */
		const xml_attribute_iterator& operator++();

		/**
		 * Post-increment operator
		 *
		 * \return old value
		 */
		xml_attribute_iterator operator++(int);
		
		/**
		 * Pre-decrement operator
		 *
		 * \return self
		 */
		const xml_attribute_iterator& operator--();
		
		/**
		 * Post-decrement operator
		 *
		 * \return old value
		 */
		xml_attribute_iterator operator--(int);
	};

	/**
	 * Abstract tree walker class
	 * \see xml_node::traverse
	 */
	class PUGIXML_CLASS xml_tree_walker
	{
		friend class xml_node;

	private:
		int _depth;
	
	protected:
		/**
		 * Get node depth
		 * 
		 * \return node depth
		 */
		int depth() const;
	
	public:
		/**
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * Default constructor
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * Virtual destructor
		 */
		virtual ~xml_tree_walker();

	public:
		/**
		 * Callback that is called when traversal of node begins.
		 *
		 * \return returning false will abort the traversal
		 */
		virtual bool begin(xml_node&);

		/**
		 * Callback that is called for each node traversed
		 *
		 * \return returning false will abort the traversal
		 */
		virtual bool for_each(xml_node&) = 0;

		/**
		 * Callback that is called when traversal of node ends.
		 *
		 * \return returning false will abort the traversal
		 */
		virtual bool end(xml_node&);
	};

	/**
	 * Struct used to distinguish parsing with ownership transfer from parsing without it.
	 * \see xml_document::parse
	 */
	struct transfer_ownership_tag {};
	/**
	 * Parsing status enumeration, returned as part of xml_parse_result struct
	 */
	enum xml_parse_status
	{
		status_ok = 0, ///< No error

		status_file_not_found, ///< File was not found during load_file()
		status_io_error, ///< Error reading from file/stream
		status_out_of_memory, ///< Could not allocate memory
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		status_internal_error, ///< Internal error occurred

		status_unrecognized_tag, ///< Parser could not determine tag type

arseny.kapoulkine's avatar
arseny.kapoulkine committed
		status_bad_pi, ///< Parsing error occurred while parsing document declaration/processing instruction (<?...?>)
		status_bad_comment, ///< Parsing error occurred while parsing comment (<!--...-->)
		status_bad_cdata, ///< Parsing error occurred while parsing CDATA section (<![CDATA[...]]>)
		status_bad_doctype, ///< Parsing error occurred while parsing document type declaration
		status_bad_pcdata, ///< Parsing error occurred while parsing PCDATA section (>...<)
		status_bad_start_element, ///< Parsing error occurred while parsing start element tag (<name ...>)
		status_bad_attribute, ///< Parsing error occurred while parsing element attribute
		status_bad_end_element, ///< Parsing error occurred while parsing end element tag (</name>)
		status_end_element_mismatch ///< There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag)
	};

	/**
	 * Parser result
	 */
	struct PUGIXML_CLASS xml_parse_result
	{
		/// Parsing status (\see xml_parse_status)
		xml_parse_status status;

		/// Last parsed offset (in bytes from file/string start)
		/// Source document encoding
		encoding_t encoding;

		/// Cast to bool operator
		operator bool() const
		{
			return status == status_ok;
		}

		/// Get error description
		const char* description() const;
	};

	/**
	 * Document class (DOM tree root).
arseny.kapoulkine's avatar
arseny.kapoulkine committed
	 * This class has non-copyable semantics (private copy constructor/assignment operator).
	 */
	class PUGIXML_CLASS xml_document: public xml_node
	{
	private:
		
		xml_document(const xml_document&);
		const xml_document& operator=(const xml_document&);

		void create();
		void destroy();

		xml_parse_result load_buffer_impl(void* contents, size_t size, unsigned int options, encoding_t encoding, bool is_mutable, bool own);

arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * Default constructor, makes empty document
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * Destructor
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * \param stream - stream with XML data
		 * \param encoding - source data encoding
		xml_parse_result load(std::basic_istream<char, std::char_traits<char> >& stream, unsigned int options = parse_default, encoding_t encoding = encoding_auto);
		/**
		 * Load document from stream.
		 *
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * \param stream - stream with XML data
		 * \param options - parsing options
		 * \return parsing result
		 */
		xml_parse_result load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options = parse_default);
		 * Load document from string. String has to be zero-terminated. No encoding conversions are applied.
		 *
		 * \param contents - input string
		 * \param options - parsing options
		 * \return parsing result
		 */
		xml_parse_result load(const char_t* contents, unsigned int options = parse_default);
		/**
		 * Parse the given XML string in-situ.
		 * The string is modified; you should ensure that string data will persist throughout the
		 * document's lifetime. Although, document does not gain ownership over the string, so you
		 * should free the memory occupied by it manually.
		 *
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * \param xmlstr - read/write string with XML data
		 * \param options - parsing options
		 * \return parsing result
		 *
		 * \deprecated This function is deprecated and will be removed in future versions; use xml_document::load_buffer_inplace instead
		PUGIXML_DEPRECATED xml_parse_result parse(char* xmlstr, unsigned int options = parse_default);
		
		/**
		 * Parse the given XML string in-situ (gains ownership).
		 * The string is modified; document gains ownership over the string, so you don't have to worry
		 * about it's lifetime.
		 * Call example: doc.parse(transfer_ownership_tag(), string, options);
		 *
arseny.kapoulkine's avatar
arseny.kapoulkine committed
		 * \param xmlstr - read/write string with XML data
		 * \param options - parsing options
		 * \return parsing result
		 *
		 * \deprecated This function is deprecated and will be removed in future versions; use xml_document::load_buffer_inplace_own instead
		PUGIXML_DEPRECATED xml_parse_result parse(const transfer_ownership_tag&, char* xmlstr, unsigned int options = parse_default);
		 * \param path - file path
		 * \param encoding - source data encoding
		xml_parse_result load_file(const char* path, unsigned int options = parse_default, encoding_t encoding = encoding_auto);
		 * Load document from buffer
		 * \param contents - buffer contents
		 * \param size - buffer size in bytes
		 * \param encoding - source data encoding
		xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, encoding_t encoding = encoding_auto);

		 * Load document from buffer in-situ.
		 * The buffer is modified; you should ensure that buffer data will persist throughout the document's
		 * lifetime. Document does not gain ownership over the buffer, so you should free the buffer memory manually.
		 * \param contents - buffer contents
		 * \param size - buffer size in bytes
		 * \param encoding - source data encoding
		xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, encoding_t encoding = encoding_auto);

		/**
		 * Load document from buffer in-situ (gains buffer ownership).
		 * The buffer is modified; you should ensure that buffer data will persist throughout the document's
		 * lifetime. Document gains ownership over the buffer, so you should allocate the buffer with pugixml
		 * allocation function.
		 *
		 * \param contents - buffer contents
		 * \param size - buffer size in bytes
		 * \param options - parsing options
		 * \param encoding - source data encoding
		 * \return parsing result
		 */
		xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, encoding_t encoding = encoding_auto);

		/**
		 * Save XML to writer
		 *
		 * \param writer - writer object
		 * \param indent - indentation string
		 * \param flags - formatting flags
		 * \param encoding - encoding used for writing
		void save(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, encoding_t encoding = encoding_auto) const;

	#ifndef PUGIXML_NO_STL
		/**
		 * Save XML to stream
		 *
		 * \param stream - output stream
		 * \param indent - indentation string
		 * \param flags - formatting flags
		 * \param encoding - encoding used for writing
		 */
		void save(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, encoding_t encoding = encoding_auto) const;

		/**
		 * Save XML to stream
		 *
		 * \param stream - output stream
		 * \param indent - indentation string
		 * \param flags - formatting flags
		 */
		void save(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const;
	#endif
		 * \param path - file path
		 * \param indent - indentation string
		 * \param flags - formatting flags
		 * \param encoding - encoding used for writing