/*␊ |
www.sourceforge.net/projects/tinyxml␊ |
Original code by Lee Thomason (www.grinninglizard.com)␊ |
␊ |
This software is provided 'as-is', without any express or implied␊ |
warranty. In no event will the authors be held liable for any␊ |
damages arising from the use of this software.␊ |
␊ |
Permission is granted to anyone to use this software for any␊ |
purpose, including commercial applications, and to alter it and␊ |
redistribute it freely, subject to the following restrictions:␊ |
␊ |
1. The origin of this software must not be misrepresented; you must␊ |
not claim that you wrote the original software. If you use this␊ |
software in a product, an acknowledgment in the product documentation␊ |
would be appreciated but is not required.␊ |
␊ |
2. Altered source versions must be plainly marked as such, and␊ |
must not be misrepresented as being the original software.␊ |
␊ |
3. This notice may not be removed or altered from any source␊ |
distribution.␊ |
*/␊ |
␊ |
␊ |
#ifndef TINYXML_INCLUDED␊ |
#define TINYXML_INCLUDED␊ |
␊ |
#ifdef _MSC_VER␊ |
#pragma warning( push )␊ |
#pragma warning( disable : 4530 )␊ |
#pragma warning( disable : 4786 )␊ |
#endif␊ |
␊ |
#include <ctype.h>␊ |
#include <stdio.h>␊ |
#include <stdlib.h>␊ |
#include <string.h>␊ |
#include <assert.h>␊ |
␊ |
// Help out windows:␊ |
#if defined( _DEBUG ) && !defined( DEBUG )␊ |
#define DEBUG␊ |
#endif␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉#include <string>␊ |
␉#include <iostream>␊ |
␉#include <sstream>␊ |
␉#define TIXML_STRING␉␉std::string␊ |
#else␊ |
␉#include "tinystr.h"␊ |
␉#define TIXML_STRING␉␉TiXmlString␊ |
#endif␊ |
␊ |
// Deprecated library function hell. Compilers want to use the␊ |
// new safe versions. This probably doesn't fully address the problem,␊ |
// but it gets closer. There are too many compilers for me to fully␊ |
// test. If you get compilation troubles, undefine TIXML_SAFE␊ |
#define TIXML_SAFE␊ |
␊ |
#ifdef TIXML_SAFE␊ |
␉#if defined(_MSC_VER) && (_MSC_VER >= 1400 )␊ |
␉␉// Microsoft visual studio, version 2005 and higher.␊ |
␉␉#define TIXML_SNPRINTF _snprintf_s␊ |
␉␉#define TIXML_SSCANF sscanf_s␊ |
␉#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )␊ |
␉␉// Microsoft visual studio, version 6 and higher.␊ |
␉␉//#pragma message( "Using _sn* functions." )␊ |
␉␉#define TIXML_SNPRINTF _snprintf␊ |
␉␉#define TIXML_SSCANF sscanf␊ |
␉#elif defined(__GNUC__) && (__GNUC__ >= 3 )␊ |
␉␉// GCC version 3 and higher.s␊ |
␉␉//#warning( "Using sn* functions." )␊ |
␉␉#define TIXML_SNPRINTF snprintf␊ |
␉␉#define TIXML_SSCANF sscanf␊ |
␉#else␊ |
␉␉#define TIXML_SNPRINTF snprintf␊ |
␉␉#define TIXML_SSCANF sscanf␊ |
␉#endif␊ |
#endif␉␊ |
␊ |
class TiXmlDocument;␊ |
class TiXmlElement;␊ |
class TiXmlComment;␊ |
class TiXmlUnknown;␊ |
class TiXmlAttribute;␊ |
class TiXmlText;␊ |
class TiXmlDeclaration;␊ |
class TiXmlParsingData;␊ |
␊ |
const int TIXML_MAJOR_VERSION = 2;␊ |
const int TIXML_MINOR_VERSION = 6;␊ |
const int TIXML_PATCH_VERSION = 2;␊ |
␊ |
/*␉Internal structure for tracking location of items ␊ |
␉in the XML file.␊ |
*/␊ |
struct TiXmlCursor␊ |
{␊ |
␉TiXmlCursor()␉␉{ Clear(); }␊ |
␉void Clear()␉␉{ row = col = -1; }␊ |
␊ |
␉int row;␉// 0 based.␊ |
␉int col;␉// 0 based.␊ |
};␊ |
␊ |
␊ |
/**␊ |
␉Implements the interface to the "Visitor pattern" (see the Accept() method.)␊ |
␉If you call the Accept() method, it requires being passed a TiXmlVisitor␊ |
␉class to handle callbacks. For nodes that contain other nodes (Document, Element)␊ |
␉you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves␊ |
␉are simply called with Visit().␊ |
␊ |
␉If you return 'true' from a Visit method, recursive parsing will continue. If you return␊ |
␉false, <b>no children of this node or its sibilings</b> will be Visited.␊ |
␊ |
␉All flavors of Visit methods have a default implementation that returns 'true' (continue ␊ |
␉visiting). You need to only override methods that are interesting to you.␊ |
␊ |
␉Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.␊ |
␊ |
␉You should never change the document from a callback.␊ |
␊ |
␉@sa TiXmlNode::Accept()␊ |
*/␊ |
class TiXmlVisitor␊ |
{␊ |
public:␊ |
␉virtual ~TiXmlVisitor() {}␊ |
␊ |
␉/// Visit a document.␊ |
␉virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )␉␉␉{ return true; }␊ |
␉/// Visit a document.␊ |
␉virtual bool VisitExit( const TiXmlDocument& /*doc*/ )␉␉␉{ return true; }␊ |
␊ |
␉/// Visit an element.␊ |
␉virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )␉{ return true; }␊ |
␉/// Visit an element.␊ |
␉virtual bool VisitExit( const TiXmlElement& /*element*/ )␉␉{ return true; }␊ |
␊ |
␉/// Visit a declaration␊ |
␉virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )␉{ return true; }␊ |
␉/// Visit a text node␊ |
␉virtual bool Visit( const TiXmlText& /*text*/ )␉␉␉␉␉{ return true; }␊ |
␉/// Visit a comment node␊ |
␉virtual bool Visit( const TiXmlComment& /*comment*/ )␉␉␉{ return true; }␊ |
␉/// Visit an unknown node␊ |
␉virtual bool Visit( const TiXmlUnknown& /*unknown*/ )␉␉␉{ return true; }␊ |
};␊ |
␊ |
// Only used by Attribute::Query functions␊ |
enum ␊ |
{ ␊ |
␉TIXML_SUCCESS,␊ |
␉TIXML_NO_ATTRIBUTE,␊ |
␉TIXML_WRONG_TYPE␊ |
};␊ |
␊ |
␊ |
// Used by the parsing routines.␊ |
enum TiXmlEncoding␊ |
{␊ |
␉TIXML_ENCODING_UNKNOWN,␊ |
␉TIXML_ENCODING_UTF8,␊ |
␉TIXML_ENCODING_LEGACY␊ |
};␊ |
␊ |
const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;␊ |
␊ |
/** TiXmlBase is a base class for every class in TinyXml.␊ |
␉It does little except to establish that TinyXml classes␊ |
␉can be printed and provide some utility functions.␊ |
␊ |
␉In XML, the document and elements can contain␊ |
␉other elements and other types of nodes.␊ |
␊ |
␉@verbatim␊ |
␉A Document can contain:␉Element␉(container or leaf)␊ |
␉␉␉␉␉␉␉Comment (leaf)␊ |
␉␉␉␉␉␉␉Unknown (leaf)␊ |
␉␉␉␉␉␉␉Declaration( leaf )␊ |
␊ |
␉An Element can contain:␉Element (container or leaf)␊ |
␉␉␉␉␉␉␉Text␉(leaf)␊ |
␉␉␉␉␉␉␉Attributes (not on tree)␊ |
␉␉␉␉␉␉␉Comment (leaf)␊ |
␉␉␉␉␉␉␉Unknown (leaf)␊ |
␊ |
␉A Decleration contains: Attributes (not on tree)␊ |
␉@endverbatim␊ |
*/␊ |
class TiXmlBase␊ |
{␊ |
␉friend class TiXmlNode;␊ |
␉friend class TiXmlElement;␊ |
␉friend class TiXmlDocument;␊ |
␊ |
public:␊ |
␉TiXmlBase()␉:␉userData(0)␉␉{}␊ |
␉virtual ~TiXmlBase()␉␉␉{}␊ |
␊ |
␉/**␉All TinyXml classes can print themselves to a filestream␊ |
␉␉or the string class (TiXmlString in non-STL mode, std::string␊ |
␉␉in STL mode.) Either or both cfile and str can be null.␊ |
␉␉␊ |
␉␉This is a formatted print, and will insert ␊ |
␉␉tabs and newlines.␊ |
␉␉␊ |
␉␉(For an unformatted stream, use the << operator.)␊ |
␉*/␊ |
␉virtual void Print( FILE* cfile, int depth ) const = 0;␊ |
␊ |
␉/**␉The world does not agree on whether white space should be kept or␊ |
␉␉not. In order to make everyone happy, these global, static functions␊ |
␉␉are provided to set whether or not TinyXml will condense all white space␊ |
␉␉into a single space or not. The default is to condense. Note changing this␊ |
␉␉value is not thread safe.␊ |
␉*/␊ |
␉static void SetCondenseWhiteSpace( bool condense )␉␉{ condenseWhiteSpace = condense; }␊ |
␊ |
␉/// Return the current white space setting.␊ |
␉static bool IsWhiteSpaceCondensed()␉␉␉␉␉␉{ return condenseWhiteSpace; }␊ |
␊ |
␉/** Return the position, in the original source file, of this node or attribute.␊ |
␉␉The row and column are 1-based. (That is the first row and first column is␊ |
␉␉1,1). If the returns values are 0 or less, then the parser does not have␊ |
␉␉a row and column value.␊ |
␊ |
␉␉Generally, the row and column value will be set when the TiXmlDocument::Load(),␊ |
␉␉TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set␊ |
␉␉when the DOM was created from operator>>.␊ |
␊ |
␉␉The values reflect the initial load. Once the DOM is modified programmatically␊ |
␉␉(by adding or changing nodes and attributes) the new values will NOT update to␊ |
␉␉reflect changes in the document.␊ |
␊ |
␉␉There is a minor performance cost to computing the row and column. Computation␊ |
␉␉can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.␊ |
␊ |
␉␉@sa TiXmlDocument::SetTabSize()␊ |
␉*/␊ |
␉int Row() const␉␉␉{ return location.row + 1; }␊ |
␉int Column() const␉␉{ return location.col + 1; }␉///< See Row()␊ |
␊ |
␉void SetUserData( void* user )␉␉␉{ userData = user; }␉///< Set a pointer to arbitrary user data.␊ |
␉void* GetUserData()␉␉␉␉␉␉{ return userData; }␉///< Get a pointer to arbitrary user data.␊ |
␉const void* GetUserData() const ␉␉{ return userData; }␉///< Get a pointer to arbitrary user data.␊ |
␊ |
␉// Table that returs, for a given lead byte, the total number of bytes␊ |
␉// in the UTF-8 sequence.␊ |
␉static const int utf8ByteTable[256];␊ |
␊ |
␉virtual const char* Parse(␉const char* p, ␊ |
␉␉␉␉␉␉␉␉TiXmlParsingData* data, ␊ |
␉␉␉␉␉␉␉␉TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;␊ |
␊ |
␉/** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, ␊ |
␉␉or they will be transformed into entities!␊ |
␉*/␊ |
␉static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );␊ |
␊ |
␉enum␊ |
␉{␊ |
␉␉TIXML_NO_ERROR = 0,␊ |
␉␉TIXML_ERROR,␊ |
␉␉TIXML_ERROR_OPENING_FILE,␊ |
␉␉TIXML_ERROR_PARSING_ELEMENT,␊ |
␉␉TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,␊ |
␉␉TIXML_ERROR_READING_ELEMENT_VALUE,␊ |
␉␉TIXML_ERROR_READING_ATTRIBUTES,␊ |
␉␉TIXML_ERROR_PARSING_EMPTY,␊ |
␉␉TIXML_ERROR_READING_END_TAG,␊ |
␉␉TIXML_ERROR_PARSING_UNKNOWN,␊ |
␉␉TIXML_ERROR_PARSING_COMMENT,␊ |
␉␉TIXML_ERROR_PARSING_DECLARATION,␊ |
␉␉TIXML_ERROR_DOCUMENT_EMPTY,␊ |
␉␉TIXML_ERROR_EMBEDDED_NULL,␊ |
␉␉TIXML_ERROR_PARSING_CDATA,␊ |
␉␉TIXML_ERROR_DOCUMENT_TOP_ONLY,␊ |
␊ |
␉␉TIXML_ERROR_STRING_COUNT␊ |
␉};␊ |
␊ |
protected:␊ |
␊ |
␉static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );␊ |
␊ |
␉inline static bool IsWhiteSpace( char c )␉␉␊ |
␉{ ␊ |
␉␉return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); ␊ |
␉}␊ |
␉inline static bool IsWhiteSpace( int c )␊ |
␉{␊ |
␉␉if ( c < 256 )␊ |
␉␉␉return IsWhiteSpace( (char) c );␊ |
␉␉return false;␉// Again, only truly correct for English/Latin...but usually works.␊ |
␉}␊ |
␊ |
␉#ifdef TIXML_USE_STL␊ |
␉static bool␉StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );␊ |
␉static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );␊ |
␉#endif␊ |
␊ |
␉/*␉Reads an XML name into the string provided. Returns␊ |
␉␉a pointer just past the last character of the name,␊ |
␉␉or 0 if the function has an error.␊ |
␉*/␊ |
␉static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );␊ |
␊ |
␉/*␉Reads text. Returns a pointer past the given end tag.␊ |
␉␉Wickedly complex options, but it keeps the (sensitive) code in one place.␊ |
␉*/␊ |
␉static const char* ReadText(␉const char* in,␉␉␉␉// where to start␊ |
␉␉␉␉␉␉␉␉␉TIXML_STRING* text,␉␉␉// the string read␊ |
␉␉␉␉␉␉␉␉␉bool ignoreWhiteSpace,␉␉// whether to keep the white space␊ |
␉␉␉␉␉␉␉␉␉const char* endTag,␉␉␉// what ends this text␊ |
␉␉␉␉␉␉␉␉␉bool ignoreCase,␉␉␉// whether to ignore case in the end tag␊ |
␉␉␉␉␉␉␉␉␉TiXmlEncoding encoding );␉// the current encoding␊ |
␊ |
␉// If an entity has been found, transform it into a character.␊ |
␉static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );␊ |
␊ |
␉// Get a character, while interpreting entities.␊ |
␉// The length can be from 0 to 4 bytes.␊ |
␉inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )␊ |
␉{␊ |
␉␉assert( p );␊ |
␉␉if ( encoding == TIXML_ENCODING_UTF8 )␊ |
␉␉{␊ |
␉␉␉*length = utf8ByteTable[ *((const unsigned char*)p) ];␊ |
␉␉␉assert( *length >= 0 && *length < 5 );␊ |
␉␉}␊ |
␉␉else␊ |
␉␉{␊ |
␉␉␉*length = 1;␊ |
␉␉}␊ |
␊ |
␉␉if ( *length == 1 )␊ |
␉␉{␊ |
␉␉␉if ( *p == '&' )␊ |
␉␉␉␉return GetEntity( p, _value, length, encoding );␊ |
␉␉␉*_value = *p;␊ |
␉␉␉return p+1;␊ |
␉␉}␊ |
␉␉else if ( *length )␊ |
␉␉{␊ |
␉␉␉//strncpy( _value, p, *length );␉// lots of compilers don't like this function (unsafe),␊ |
␉␉␉␉␉␉␉␉␉␉␉␉// and the null terminator isn't needed␊ |
␉␉␉for( int i=0; p[i] && i<*length; ++i ) {␊ |
␉␉␉␉_value[i] = p[i];␊ |
␉␉␉}␊ |
␉␉␉return p + (*length);␊ |
␉␉}␊ |
␉␉else␊ |
␉␉{␊ |
␉␉␉// Not valid text.␊ |
␉␉␉return 0;␊ |
␉␉}␊ |
␉}␊ |
␊ |
␉// Return true if the next characters in the stream are any of the endTag sequences.␊ |
␉// Ignore case only works for english, and should only be relied on when comparing␊ |
␉// to English words: StringEqual( p, "version", true ) is fine.␊ |
␉static bool StringEqual(␉const char* p,␊ |
␉␉␉␉␉␉␉␉const char* endTag,␊ |
␉␉␉␉␉␉␉␉bool ignoreCase,␊ |
␉␉␉␉␉␉␉␉TiXmlEncoding encoding );␊ |
␊ |
␉static const char* errorString[ TIXML_ERROR_STRING_COUNT ];␊ |
␊ |
␉TiXmlCursor location;␊ |
␊ |
/// Field containing a generic user pointer␊ |
␉void*␉␉␉userData;␊ |
␉␊ |
␉// None of these methods are reliable for any language except English.␊ |
␉// Good for approximation, not great for accuracy.␊ |
␉static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );␊ |
␉static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );␊ |
␉inline static int ToLower( int v, TiXmlEncoding encoding )␊ |
␉{␊ |
␉␉if ( encoding == TIXML_ENCODING_UTF8 )␊ |
␉␉{␊ |
␉␉␉if ( v < 128 ) return tolower( v );␊ |
␉␉␉return v;␊ |
␉␉}␊ |
␉␉else␊ |
␉␉{␊ |
␉␉␉return tolower( v );␊ |
␉␉}␊ |
␉}␊ |
␉static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );␊ |
␊ |
private:␊ |
␉TiXmlBase( const TiXmlBase& );␉␉␉␉// not implemented.␊ |
␉void operator=( const TiXmlBase& base );␉// not allowed.␊ |
␊ |
␉struct Entity␊ |
␉{␊ |
␉␉const char* str;␊ |
␉␉unsigned int␉strLength;␊ |
␉␉char␉␉ chr;␊ |
␉};␊ |
␉enum␊ |
␉{␊ |
␉␉NUM_ENTITY = 5,␊ |
␉␉MAX_ENTITY_LENGTH = 6␊ |
␊ |
␉};␊ |
␉static Entity entity[ NUM_ENTITY ];␊ |
␉static bool condenseWhiteSpace;␊ |
};␊ |
␊ |
␊ |
/** The parent class for everything in the Document Object Model.␊ |
␉(Except for attributes).␊ |
␉Nodes have siblings, a parent, and children. A node can be␊ |
␉in a document, or stand on its own. The type of a TiXmlNode␊ |
␉can be queried, and it can be cast to its more defined type.␊ |
*/␊ |
class TiXmlNode : public TiXmlBase␊ |
{␊ |
␉friend class TiXmlDocument;␊ |
␉friend class TiXmlElement;␊ |
␊ |
public:␊ |
␉#ifdef TIXML_USE_STL␉␊ |
␊ |
␉ /** An input stream operator, for every class. Tolerant of newlines and␊ |
␉␉ formatting, but doesn't expect them.␊ |
␉ */␊ |
␉ friend std::istream& operator >> (std::istream& in, TiXmlNode& base);␊ |
␊ |
␉ /** An output stream operator, for every class. Note that this outputs␊ |
␉␉ without any newlines or formatting, as opposed to Print(), which␊ |
␉␉ includes tabs and new lines.␊ |
␊ |
␉␉ The operator<< and operator>> are not completely symmetric. Writing␊ |
␉␉ a node to a stream is very well defined. You'll get a nice stream␊ |
␉␉ of output, without any extra whitespace or newlines.␊ |
␉␉ ␊ |
␉␉ But reading is not as well defined. (As it always is.) If you create␊ |
␉␉ a TiXmlElement (for example) and read that from an input stream,␊ |
␉␉ the text needs to define an element or junk will result. This is␊ |
␉␉ true of all input streams, but it's worth keeping in mind.␊ |
␊ |
␉␉ A TiXmlDocument will read nodes until it reads a root element, and␊ |
␉␉␉all the children of that root element.␊ |
␉ */␉␊ |
␉ friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);␊ |
␊ |
␉␉/// Appends the XML node or attribute to a std::string.␊ |
␉␉friend std::string& operator<< (std::string& out, const TiXmlNode& base );␊ |
␊ |
␉#endif␊ |
␊ |
␉/** The types of XML nodes supported by TinyXml. (All the␊ |
␉␉␉unsupported types are picked up by UNKNOWN.)␊ |
␉*/␊ |
␉enum NodeType␊ |
␉{␊ |
␉␉TINYXML_DOCUMENT,␊ |
␉␉TINYXML_ELEMENT,␊ |
␉␉TINYXML_COMMENT,␊ |
␉␉TINYXML_UNKNOWN,␊ |
␉␉TINYXML_TEXT,␊ |
␉␉TINYXML_DECLARATION,␊ |
␉␉TINYXML_TYPECOUNT␊ |
␉};␊ |
␊ |
␉virtual ~TiXmlNode();␊ |
␊ |
␉/** The meaning of 'value' changes for the specific type of␊ |
␉␉TiXmlNode.␊ |
␉␉@verbatim␊ |
␉␉Document:␉filename of the xml file␊ |
␉␉Element:␉name of the element␊ |
␉␉Comment:␉the comment text␊ |
␉␉Unknown:␉the tag contents␊ |
␉␉Text:␉␉the text string␊ |
␉␉@endverbatim␊ |
␊ |
␉␉The subclasses will wrap this function.␊ |
␉*/␊ |
␉const char *Value() const { return value.c_str (); }␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉/** Return Value() as a std::string. If you only use STL,␊ |
␉ this is more efficient than calling Value().␊ |
␉␉Only available in STL mode.␊ |
␉*/␊ |
␉const std::string& ValueStr() const { return value; }␊ |
␉#endif␊ |
␊ |
␉const TIXML_STRING& ValueTStr() const { return value; }␊ |
␊ |
␉/** Changes the value of the node. Defined as:␊ |
␉␉@verbatim␊ |
␉␉Document:␉filename of the xml file␊ |
␉␉Element:␉name of the element␊ |
␉␉Comment:␉the comment text␊ |
␉␉Unknown:␉the tag contents␊ |
␉␉Text:␉␉the text string␊ |
␉␉@endverbatim␊ |
␉*/␊ |
␉void SetValue(const char * _value) { value = _value;}␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉/// STL std::string form.␊ |
␉void SetValue( const std::string& _value )␉{ value = _value; }␊ |
␉#endif␊ |
␊ |
␉/// Delete all the children of this node. Does not affect 'this'.␊ |
␉void Clear();␊ |
␊ |
␉/// One step up the DOM.␊ |
␉TiXmlNode* Parent()␉␉␉␉␉␉␉{ return parent; }␊ |
␉const TiXmlNode* Parent() const␉␉␉␉{ return parent; }␊ |
␊ |
␉const TiXmlNode* FirstChild()␉const␉␉{ return firstChild; }␉///< The first child of this node. Will be null if there are no children.␊ |
␉TiXmlNode* FirstChild()␉␉␉␉␉␉{ return firstChild; }␊ |
␉const TiXmlNode* FirstChild( const char * value ) const;␉␉␉///< The first child of this node with the matching 'value'. Will be null if none found.␊ |
␉/// The first child of this node with the matching 'value'. Will be null if none found.␊ |
␉TiXmlNode* FirstChild( const char * _value ) {␊ |
␉␉// Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)␊ |
␉␉// call the method, cast the return back to non-const.␊ |
␉␉return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));␊ |
␉}␊ |
␉const TiXmlNode* LastChild() const␉{ return lastChild; }␉␉/// The last child of this node. Will be null if there are no children.␊ |
␉TiXmlNode* LastChild()␉{ return lastChild; }␊ |
␉␊ |
␉const TiXmlNode* LastChild( const char * value ) const;␉␉␉/// The last child of this node matching 'value'. Will be null if there are no children.␊ |
␉TiXmlNode* LastChild( const char * _value ) {␊ |
␉␉return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));␊ |
␉}␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉const TiXmlNode* FirstChild( const std::string& _value ) const␉{␉return FirstChild (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉TiXmlNode* FirstChild( const std::string& _value )␉␉␉␉{␉return FirstChild (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉const TiXmlNode* LastChild( const std::string& _value ) const␉{␉return LastChild (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉TiXmlNode* LastChild( const std::string& _value )␉␉␉␉{␉return LastChild (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉#endif␊ |
␊ |
␉/** An alternate way to walk the children of a node.␊ |
␉␉One way to iterate over nodes is:␊ |
␉␉@verbatim␊ |
␉␉␉for( child = parent->FirstChild(); child; child = child->NextSibling() )␊ |
␉␉@endverbatim␊ |
␊ |
␉␉IterateChildren does the same thing with the syntax:␊ |
␉␉@verbatim␊ |
␉␉␉child = 0;␊ |
␉␉␉while( child = parent->IterateChildren( child ) )␊ |
␉␉@endverbatim␊ |
␊ |
␉␉IterateChildren takes the previous child as input and finds␊ |
␉␉the next one. If the previous child is null, it returns the␊ |
␉␉first. IterateChildren will return null when done.␊ |
␉*/␊ |
␉const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;␊ |
␉TiXmlNode* IterateChildren( const TiXmlNode* previous ) {␊ |
␉␉return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );␊ |
␉}␊ |
␊ |
␉/// This flavor of IterateChildren searches for children with a particular 'value'␊ |
␉const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;␊ |
␉TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {␊ |
␉␉return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );␊ |
␉}␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const␉{␉return IterateChildren (_value.c_str (), previous);␉}␉///< STL std::string form.␊ |
␉TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {␉return IterateChildren (_value.c_str (), previous);␉}␉///< STL std::string form.␊ |
␉#endif␊ |
␊ |
␉/** Add a new node related to this. Adds a child past the LastChild.␊ |
␉␉Returns a pointer to the new object or NULL if an error occured.␊ |
␉*/␊ |
␉TiXmlNode* InsertEndChild( const TiXmlNode& addThis );␊ |
␊ |
␊ |
␉/** Add a new node related to this. Adds a child past the LastChild.␊ |
␊ |
␉␉NOTE: the node to be added is passed by pointer, and will be␊ |
␉␉henceforth owned (and deleted) by tinyXml. This method is efficient␊ |
␉␉and avoids an extra copy, but should be used with care as it␊ |
␉␉uses a different memory model than the other insert functions.␊ |
␊ |
␉␉@sa InsertEndChild␊ |
␉*/␊ |
␉TiXmlNode* LinkEndChild( TiXmlNode* addThis );␊ |
␊ |
␉/** Add a new node related to this. Adds a child before the specified child.␊ |
␉␉Returns a pointer to the new object or NULL if an error occured.␊ |
␉*/␊ |
␉TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );␊ |
␊ |
␉/** Add a new node related to this. Adds a child after the specified child.␊ |
␉␉Returns a pointer to the new object or NULL if an error occured.␊ |
␉*/␊ |
␉TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );␊ |
␊ |
␉/** Replace a child of this node.␊ |
␉␉Returns a pointer to the new object or NULL if an error occured.␊ |
␉*/␊ |
␉TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );␊ |
␊ |
␉/// Delete a child of this node.␊ |
␉bool RemoveChild( TiXmlNode* removeThis );␊ |
␊ |
␉/// Navigate to a sibling node.␊ |
␉const TiXmlNode* PreviousSibling() const␉␉␉{ return prev; }␊ |
␉TiXmlNode* PreviousSibling()␉␉␉␉␉␉{ return prev; }␊ |
␊ |
␉/// Navigate to a sibling node.␊ |
␉const TiXmlNode* PreviousSibling( const char * ) const;␊ |
␉TiXmlNode* PreviousSibling( const char *_prev ) {␊ |
␉␉return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );␊ |
␉}␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉const TiXmlNode* PreviousSibling( const std::string& _value ) const␉{␉return PreviousSibling (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉TiXmlNode* PreviousSibling( const std::string& _value ) ␉␉␉{␉return PreviousSibling (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉const TiXmlNode* NextSibling( const std::string& _value) const␉␉{␉return NextSibling (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉TiXmlNode* NextSibling( const std::string& _value) ␉␉␉␉␉{␉return NextSibling (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉#endif␊ |
␊ |
␉/// Navigate to a sibling node.␊ |
␉const TiXmlNode* NextSibling() const␉␉␉␉{ return next; }␊ |
␉TiXmlNode* NextSibling()␉␉␉␉␉␉␉{ return next; }␊ |
␊ |
␉/// Navigate to a sibling node with the given 'value'.␊ |
␉const TiXmlNode* NextSibling( const char * ) const;␊ |
␉TiXmlNode* NextSibling( const char* _next ) {␊ |
␉␉return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );␊ |
␉}␊ |
␊ |
␉/** Convenience function to get through elements.␊ |
␉␉Calls NextSibling and ToElement. Will skip all non-Element␊ |
␉␉nodes. Returns 0 if there is not another element.␊ |
␉*/␊ |
␉const TiXmlElement* NextSiblingElement() const;␊ |
␉TiXmlElement* NextSiblingElement() {␊ |
␉␉return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );␊ |
␉}␊ |
␊ |
␉/** Convenience function to get through elements.␊ |
␉␉Calls NextSibling and ToElement. Will skip all non-Element␊ |
␉␉nodes. Returns 0 if there is not another element.␊ |
␉*/␊ |
␉const TiXmlElement* NextSiblingElement( const char * ) const;␊ |
␉TiXmlElement* NextSiblingElement( const char *_next ) {␊ |
␉␉return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );␊ |
␉}␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉const TiXmlElement* NextSiblingElement( const std::string& _value) const␉{␉return NextSiblingElement (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉TiXmlElement* NextSiblingElement( const std::string& _value)␉␉␉␉{␉return NextSiblingElement (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉#endif␊ |
␊ |
␉/// Convenience function to get through elements.␊ |
␉const TiXmlElement* FirstChildElement()␉const;␊ |
␉TiXmlElement* FirstChildElement() {␊ |
␉␉return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );␊ |
␉}␊ |
␊ |
␉/// Convenience function to get through elements.␊ |
␉const TiXmlElement* FirstChildElement( const char * _value ) const;␊ |
␉TiXmlElement* FirstChildElement( const char * _value ) {␊ |
␉␉return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );␊ |
␉}␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉const TiXmlElement* FirstChildElement( const std::string& _value ) const␉{␉return FirstChildElement (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉TiXmlElement* FirstChildElement( const std::string& _value )␉␉␉␉{␉return FirstChildElement (_value.c_str ());␉}␉///< STL std::string form.␊ |
␉#endif␊ |
␊ |
␉/** Query the type (as an enumerated value, above) of this node.␊ |
␉␉The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT,␊ |
␉␉␉␉␉␉␉␉TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION.␊ |
␉*/␊ |
␉int Type() const␉{ return type; }␊ |
␊ |
␉/** Return a pointer to the Document this node lives in.␊ |
␉␉Returns null if not in a document.␊ |
␉*/␊ |
␉const TiXmlDocument* GetDocument() const;␊ |
␉TiXmlDocument* GetDocument() {␊ |
␉␉return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );␊ |
␉}␊ |
␊ |
␉/// Returns true if this node has no children.␊ |
␉bool NoChildren() const␉␉␉␉␉␉{ return !firstChild; }␊ |
␊ |
␉virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␉virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␉virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␉virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␉virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␉virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␊ |
␉virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␉virtual TiXmlElement* ToElement()␉ { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␉virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␉virtual TiXmlUnknown* ToUnknown()␉ { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␉virtual TiXmlText*␉ ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␉virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.␊ |
␊ |
␉/** Create an exact duplicate of this node and return it. The memory must be deleted␊ |
␉␉by the caller. ␊ |
␉*/␊ |
␉virtual TiXmlNode* Clone() const = 0;␊ |
␊ |
␉/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the ␊ |
␉␉XML tree will be conditionally visited and the host will be called back␊ |
␉␉via the TiXmlVisitor interface.␊ |
␊ |
␉␉This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse␊ |
␉␉the XML for the callbacks, so the performance of TinyXML is unchanged by using this␊ |
␉␉interface versus any other.)␊ |
␊ |
␉␉The interface has been based on ideas from:␊ |
␊ |
␉␉- http://www.saxproject.org/␊ |
␉␉- http://c2.com/cgi/wiki?HierarchicalVisitorPattern ␊ |
␊ |
␉␉Which are both good references for "visiting".␊ |
␊ |
␉␉An example of using Accept():␊ |
␉␉@verbatim␊ |
␉␉TiXmlPrinter printer;␊ |
␉␉tinyxmlDoc.Accept( &printer );␊ |
␉␉const char* xmlcstr = printer.CStr();␊ |
␉␉@endverbatim␊ |
␉*/␊ |
␉virtual bool Accept( TiXmlVisitor* visitor ) const = 0;␊ |
␊ |
protected:␊ |
␉TiXmlNode( NodeType _type );␊ |
␊ |
␉// Copy to the allocated object. Shared functionality between Clone, Copy constructor,␊ |
␉// and the assignment operator.␊ |
␉void CopyTo( TiXmlNode* target ) const;␊ |
␊ |
␉#ifdef TIXML_USE_STL␊ |
␉ // The real work of the input operator.␊ |
␉virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;␊ |
␉#endif␊ |
␊ |
␉// Figure out what is at *p, and parse it. Returns null if it is not an xml node.␊ |
␉TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );␊ |
␊ |
␉TiXmlNode*␉␉parent;␊ |
␉NodeType␉␉type;␊ |
␊ |
␉TiXmlNode*␉␉firstChild;␊ |
␉TiXmlNode*␉␉lastChild;␊ |
␊ |
␉TIXML_STRING␉value;␊ |
␊ |
␉TiXmlNode*␉␉prev;␊ |
␉TiXmlNode*␉␉next;␊ |
␊ |
private:␊ |
␉TiXmlNode( const TiXmlNode& );␉␉␉␉// not implemented.␊ |
␉void operator=( const TiXmlNode& base );␉// not allowed.␊ |
};␊ |
␊ |
␊ |
/** An attribute is a name-value pair. Elements have an arbitrary␊ |
␉number of attributes, each with a unique name.␊ |
␊ |
␉@note The attributes are not TiXmlNodes, since they are not␊ |
␉␉ part of the tinyXML document object model. There are other␊ |
␉␉ suggested ways to look at this problem.␊ |
*/␊ |
class TiXmlAttribute : public TiXmlBase␊ |
{␊ |
␉friend class TiXmlAttributeSet;␊ |
␊ |
public:␊ |
␉/// Construct an empty attribute.␊ |
␉TiXmlAttribute() : TiXmlBase()␊ |
␉{␊ |
␉␉document = 0;␊ |
␉␉prev = next = 0;␊ |
␉}␊ |
␊ |
␉#ifdef TIXML_USE_STL␊ |
␉/// std::string constructor.␊ |
␉TiXmlAttribute( const std::string& _name, const std::string& _value )␊ |
␉{␊ |
␉␉name = _name;␊ |
␉␉value = _value;␊ |
␉␉document = 0;␊ |
␉␉prev = next = 0;␊ |
␉}␊ |
␉#endif␊ |
␊ |
␉/// Construct an attribute with a name and value.␊ |
␉TiXmlAttribute( const char * _name, const char * _value )␊ |
␉{␊ |
␉␉name = _name;␊ |
␉␉value = _value;␊ |
␉␉document = 0;␊ |
␉␉prev = next = 0;␊ |
␉}␊ |
␊ |
␉const char*␉␉Name() const␉␉{ return name.c_str(); }␉␉///< Return the name of this attribute.␊ |
␉const char*␉␉Value() const␉␉{ return value.c_str(); }␉␉///< Return the value of this attribute.␊ |
␉#ifdef TIXML_USE_STL␊ |
␉const std::string& ValueStr() const␉{ return value; }␉␉␉␉///< Return the value of this attribute.␊ |
␉#endif␊ |
␉int␉␉␉␉IntValue() const;␉␉␉␉␉␉␉␉␉///< Return the value of this attribute, converted to an integer.␊ |
␉double␉␉␉DoubleValue() const;␉␉␉␉␉␉␉␉///< Return the value of this attribute, converted to a double.␊ |
␊ |
␉// Get the tinyxml string representation␊ |
␉const TIXML_STRING& NameTStr() const { return name; }␊ |
␊ |
␉/** QueryIntValue examines the value string. It is an alternative to the␊ |
␉␉IntValue() method with richer error checking.␊ |
␉␉If the value is an integer, it is stored in 'value' and ␊ |
␉␉the call returns TIXML_SUCCESS. If it is not␊ |
␉␉an integer, it returns TIXML_WRONG_TYPE.␊ |
␊ |
␉␉A specialized but useful call. Note that for success it returns 0,␊ |
␉␉which is the opposite of almost all other TinyXml calls.␊ |
␉*/␊ |
␉int QueryIntValue( int* _value ) const;␊ |
␉/// QueryDoubleValue examines the value string. See QueryIntValue().␊ |
␉int QueryDoubleValue( double* _value ) const;␊ |
␊ |
␉void SetName( const char* _name )␉{ name = _name; }␉␉␉␉///< Set the name of this attribute.␊ |
␉void SetValue( const char* _value )␉{ value = _value; }␉␉␉␉///< Set the value.␊ |
␊ |
␉void SetIntValue( int _value );␉␉␉␉␉␉␉␉␉␉///< Set the value from an integer.␊ |
␉void SetDoubleValue( double _value );␉␉␉␉␉␉␉␉///< Set the value from a double.␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉/// STL std::string form.␊ |
␉void SetName( const std::string& _name )␉{ name = _name; }␉␊ |
␉/// STL std::string form.␉␊ |
␉void SetValue( const std::string& _value )␉{ value = _value; }␊ |
␉#endif␊ |
␊ |
␉/// Get the next sibling attribute in the DOM. Returns null at end.␊ |
␉const TiXmlAttribute* Next() const;␊ |
␉TiXmlAttribute* Next() {␊ |
␉␉return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); ␊ |
␉}␊ |
␊ |
␉/// Get the previous sibling attribute in the DOM. Returns null at beginning.␊ |
␉const TiXmlAttribute* Previous() const;␊ |
␉TiXmlAttribute* Previous() {␊ |
␉␉return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); ␊ |
␉}␊ |
␊ |
␉bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }␊ |
␉bool operator<( const TiXmlAttribute& rhs )␉ const { return name < rhs.name; }␊ |
␉bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; }␊ |
␊ |
␉/*␉Attribute parsing starts: first letter of the name␊ |
␉␉␉␉␉␉ returns: the next char after the value end quote␊ |
␉*/␊ |
␉virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );␊ |
␊ |
␉// Prints this Attribute to a FILE stream.␊ |
␉virtual void Print( FILE* cfile, int depth ) const {␊ |
␉␉Print( cfile, depth, 0 );␊ |
␉}␊ |
␉void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;␊ |
␊ |
␉// [internal use]␊ |
␉// Set the document pointer so the attribute can report errors.␊ |
␉void SetDocument( TiXmlDocument* doc )␉{ document = doc; }␊ |
␊ |
private:␊ |
␉TiXmlAttribute( const TiXmlAttribute& );␉␉␉␉// not implemented.␊ |
␉void operator=( const TiXmlAttribute& base );␉// not allowed.␊ |
␊ |
␉TiXmlDocument*␉document;␉// A pointer back to a document, for error reporting.␊ |
␉TIXML_STRING name;␊ |
␉TIXML_STRING value;␊ |
␉TiXmlAttribute*␉prev;␊ |
␉TiXmlAttribute*␉next;␊ |
};␊ |
␊ |
␊ |
/*␉A class used to manage a group of attributes.␊ |
␉It is only used internally, both by the ELEMENT and the DECLARATION.␊ |
␉␊ |
␉The set can be changed transparent to the Element and Declaration␊ |
␉classes that use it, but NOT transparent to the Attribute␊ |
␉which has to implement a next() and previous() method. Which makes␊ |
␉it a bit problematic and prevents the use of STL.␊ |
␊ |
␉This version is implemented with circular lists because:␊ |
␉␉- I like circular lists␊ |
␉␉- it demonstrates some independence from the (typical) doubly linked list.␊ |
*/␊ |
class TiXmlAttributeSet␊ |
{␊ |
public:␊ |
␉TiXmlAttributeSet();␊ |
␉~TiXmlAttributeSet();␊ |
␊ |
␉void Add( TiXmlAttribute* attribute );␊ |
␉void Remove( TiXmlAttribute* attribute );␊ |
␊ |
␉const TiXmlAttribute* First()␉const␉{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }␊ |
␉TiXmlAttribute* First()␉␉␉␉␉{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }␊ |
␉const TiXmlAttribute* Last() const␉␉{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }␊ |
␉TiXmlAttribute* Last()␉␉␉␉␉{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }␊ |
␊ |
␉TiXmlAttribute*␉Find( const char* _name ) const;␊ |
␉TiXmlAttribute* FindOrCreate( const char* _name );␊ |
␊ |
#␉ifdef TIXML_USE_STL␊ |
␉TiXmlAttribute*␉Find( const std::string& _name ) const;␊ |
␉TiXmlAttribute* FindOrCreate( const std::string& _name );␊ |
#␉endif␊ |
␊ |
␊ |
private:␊ |
␉//*ME:␉Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),␊ |
␉//*ME:␉this class must be also use a hidden/disabled copy-constructor !!!␊ |
␉TiXmlAttributeSet( const TiXmlAttributeSet& );␉// not allowed␊ |
␉void operator=( const TiXmlAttributeSet& );␉// not allowed (as TiXmlAttribute)␊ |
␊ |
␉TiXmlAttribute sentinel;␊ |
};␊ |
␊ |
␊ |
/** The element is a container class. It has a value, the element name,␊ |
␉and can contain other elements, text, comments, and unknowns.␊ |
␉Elements also contain an arbitrary number of attributes.␊ |
*/␊ |
class TiXmlElement : public TiXmlNode␊ |
{␊ |
public:␊ |
␉/// Construct an element.␊ |
␉TiXmlElement (const char * in_value);␊ |
␊ |
␉#ifdef TIXML_USE_STL␊ |
␉/// std::string constructor.␊ |
␉TiXmlElement( const std::string& _value );␊ |
␉#endif␊ |
␊ |
␉TiXmlElement( const TiXmlElement& );␊ |
␊ |
␉TiXmlElement& operator=( const TiXmlElement& base );␊ |
␊ |
␉virtual ~TiXmlElement();␊ |
␊ |
␉/** Given an attribute name, Attribute() returns the value␊ |
␉␉for the attribute of that name, or null if none exists.␊ |
␉*/␊ |
␉const char* Attribute( const char* name ) const;␊ |
␊ |
␉/** Given an attribute name, Attribute() returns the value␊ |
␉␉for the attribute of that name, or null if none exists.␊ |
␉␉If the attribute exists and can be converted to an integer,␊ |
␉␉the integer value will be put in the return 'i', if 'i'␊ |
␉␉is non-null.␊ |
␉*/␊ |
␉const char* Attribute( const char* name, int* i ) const;␊ |
␊ |
␉/** Given an attribute name, Attribute() returns the value␊ |
␉␉for the attribute of that name, or null if none exists.␊ |
␉␉If the attribute exists and can be converted to an double,␊ |
␉␉the double value will be put in the return 'd', if 'd'␊ |
␉␉is non-null.␊ |
␉*/␊ |
␉const char* Attribute( const char* name, double* d ) const;␊ |
␊ |
␉/** QueryIntAttribute examines the attribute - it is an alternative to the␊ |
␉␉Attribute() method with richer error checking.␊ |
␉␉If the attribute is an integer, it is stored in 'value' and ␊ |
␉␉the call returns TIXML_SUCCESS. If it is not␊ |
␉␉an integer, it returns TIXML_WRONG_TYPE. If the attribute␊ |
␉␉does not exist, then TIXML_NO_ATTRIBUTE is returned.␊ |
␉*/␉␊ |
␉int QueryIntAttribute( const char* name, int* _value ) const;␊ |
␉/// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute().␊ |
␉int QueryUnsignedAttribute( const char* name, unsigned* _value ) const;␊ |
␉/** QueryBoolAttribute examines the attribute - see QueryIntAttribute(). ␊ |
␉␉Note that '1', 'true', or 'yes' are considered true, while '0', 'false'␊ |
␉␉and 'no' are considered false.␊ |
␉*/␊ |
␉int QueryBoolAttribute( const char* name, bool* _value ) const;␊ |
␉/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().␊ |
␉int QueryDoubleAttribute( const char* name, double* _value ) const;␊ |
␉/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().␊ |
␉int QueryFloatAttribute( const char* name, float* _value ) const {␊ |
␉␉double d;␊ |
␉␉int result = QueryDoubleAttribute( name, &d );␊ |
␉␉if ( result == TIXML_SUCCESS ) {␊ |
␉␉␉*_value = (float)d;␊ |
␉␉}␊ |
␉␉return result;␊ |
␉}␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉/// QueryStringAttribute examines the attribute - see QueryIntAttribute().␊ |
␉int QueryStringAttribute( const char* name, std::string* _value ) const {␊ |
␉␉const char* cstr = Attribute( name );␊ |
␉␉if ( cstr ) {␊ |
␉␉␉*_value = std::string( cstr );␊ |
␉␉␉return TIXML_SUCCESS;␊ |
␉␉}␊ |
␉␉return TIXML_NO_ATTRIBUTE;␊ |
␉}␊ |
␊ |
␉/** Template form of the attribute query which will try to read the␊ |
␉␉attribute into the specified type. Very easy, very powerful, but␊ |
␉␉be careful to make sure to call this with the correct type.␊ |
␉␉␊ |
␉␉NOTE: This method doesn't work correctly for 'string' types that contain spaces.␊ |
␊ |
␉␉@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE␊ |
␉*/␊ |
␉template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const␊ |
␉{␊ |
␉␉const TiXmlAttribute* node = attributeSet.Find( name );␊ |
␉␉if ( !node )␊ |
␉␉␉return TIXML_NO_ATTRIBUTE;␊ |
␊ |
␉␉std::stringstream sstream( node->ValueStr() );␊ |
␉␉sstream >> *outValue;␊ |
␉␉if ( !sstream.fail() )␊ |
␉␉␉return TIXML_SUCCESS;␊ |
␉␉return TIXML_WRONG_TYPE;␊ |
␉}␊ |
␊ |
␉int QueryValueAttribute( const std::string& name, std::string* outValue ) const␊ |
␉{␊ |
␉␉const TiXmlAttribute* node = attributeSet.Find( name );␊ |
␉␉if ( !node )␊ |
␉␉␉return TIXML_NO_ATTRIBUTE;␊ |
␉␉*outValue = node->ValueStr();␊ |
␉␉return TIXML_SUCCESS;␊ |
␉}␊ |
␉#endif␊ |
␊ |
␉/** Sets an attribute of name to a given value. The attribute␊ |
␉␉will be created if it does not exist, or changed if it does.␊ |
␉*/␊ |
␉void SetAttribute( const char* name, const char * _value );␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉const std::string* Attribute( const std::string& name ) const;␊ |
␉const std::string* Attribute( const std::string& name, int* i ) const;␊ |
␉const std::string* Attribute( const std::string& name, double* d ) const;␊ |
␉int QueryIntAttribute( const std::string& name, int* _value ) const;␊ |
␉int QueryDoubleAttribute( const std::string& name, double* _value ) const;␊ |
␊ |
␉/// STL std::string form.␊ |
␉void SetAttribute( const std::string& name, const std::string& _value );␊ |
␉///< STL std::string form.␊ |
␉void SetAttribute( const std::string& name, int _value );␊ |
␉///< STL std::string form.␊ |
␉void SetDoubleAttribute( const std::string& name, double value );␊ |
␉#endif␊ |
␊ |
␉/** Sets an attribute of name to a given value. The attribute␊ |
␉␉will be created if it does not exist, or changed if it does.␊ |
␉*/␊ |
␉void SetAttribute( const char * name, int value );␊ |
␊ |
␉/** Sets an attribute of name to a given value. The attribute␊ |
␉␉will be created if it does not exist, or changed if it does.␊ |
␉*/␊ |
␉void SetDoubleAttribute( const char * name, double value );␊ |
␊ |
␉/** Deletes an attribute with the given name.␊ |
␉*/␊ |
␉void RemoveAttribute( const char * name );␊ |
#ifdef TIXML_USE_STL␊ |
␉void RemoveAttribute( const std::string& name )␉{␉RemoveAttribute (name.c_str ());␉}␉///< STL std::string form.␊ |
␉#endif␊ |
␊ |
␉const TiXmlAttribute* FirstAttribute() const␉{ return attributeSet.First(); }␉␉///< Access the first attribute in this element.␊ |
␉TiXmlAttribute* FirstAttribute() ␉␉␉␉{ return attributeSet.First(); }␊ |
␉const TiXmlAttribute* LastAttribute()␉const ␉{ return attributeSet.Last(); }␉␉///< Access the last attribute in this element.␊ |
␉TiXmlAttribute* LastAttribute()␉␉␉␉␉{ return attributeSet.Last(); }␊ |
␊ |
␉/** Convenience function for easy access to the text inside an element. Although easy␊ |
␉␉and concise, GetText() is limited compared to getting the TiXmlText child␊ |
␉␉and accessing it directly.␊ |
␉␊ |
␉␉If the first child of 'this' is a TiXmlText, the GetText()␊ |
␉␉returns the character string of the Text node, else null is returned.␊ |
␊ |
␉␉This is a convenient method for getting the text of simple contained text:␊ |
␉␉@verbatim␊ |
␉␉<foo>This is text</foo>␊ |
␉␉const char* str = fooElement->GetText();␊ |
␉␉@endverbatim␊ |
␊ |
␉␉'str' will be a pointer to "This is text". ␊ |
␉␉␊ |
␉␉Note that this function can be misleading. If the element foo was created from␊ |
␉␉this XML:␊ |
␉␉@verbatim␊ |
␉␉<foo><b>This is text</b></foo> ␊ |
␉␉@endverbatim␊ |
␊ |
␉␉then the value of str would be null. The first child node isn't a text node, it is␊ |
␉␉another element. From this XML:␊ |
␉␉@verbatim␊ |
␉␉<foo>This is <b>text</b></foo> ␊ |
␉␉@endverbatim␊ |
␉␉GetText() will return "This is ".␊ |
␊ |
␉␉WARNING: GetText() accesses a child node - don't become confused with the ␊ |
␉␉␉␉ similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are ␊ |
␉␉␉␉ safe type casts on the referenced node.␊ |
␉*/␊ |
␉const char* GetText() const;␊ |
␊ |
␉/// Creates a new Element and returns it - the returned element is a copy.␊ |
␉virtual TiXmlNode* Clone() const;␊ |
␉// Print the Element to a FILE stream.␊ |
␉virtual void Print( FILE* cfile, int depth ) const;␊ |
␊ |
␉/*␉Attribtue parsing starts: next char past '<'␊ |
␉␉␉␉␉␉ returns: next char past '>'␊ |
␉*/␊ |
␉virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );␊ |
␊ |
␉virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␉virtual TiXmlElement* ToElement()␉ { return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␊ |
␉/** Walk the XML tree visiting this node and all of its children. ␊ |
␉*/␊ |
␉virtual bool Accept( TiXmlVisitor* visitor ) const;␊ |
␊ |
protected:␊ |
␊ |
␉void CopyTo( TiXmlElement* target ) const;␊ |
␉void ClearThis();␉// like clear, but initializes 'this' object as well␊ |
␊ |
␉// Used to be public [internal use]␊ |
␉#ifdef TIXML_USE_STL␊ |
␉virtual void StreamIn( std::istream * in, TIXML_STRING * tag );␊ |
␉#endif␊ |
␉/*␉[internal use]␊ |
␉␉Reads the "value" of the element -- another element, or text.␊ |
␉␉This should terminate with the current end tag.␊ |
␉*/␊ |
␉const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );␊ |
␊ |
private:␊ |
␉TiXmlAttributeSet attributeSet;␊ |
};␊ |
␊ |
␊ |
/**␉An XML comment.␊ |
*/␊ |
class TiXmlComment : public TiXmlNode␊ |
{␊ |
public:␊ |
␉/// Constructs an empty comment.␊ |
␉TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {}␊ |
␉/// Construct a comment from text.␊ |
␉TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {␊ |
␉␉SetValue( _value );␊ |
␉}␊ |
␉TiXmlComment( const TiXmlComment& );␊ |
␉TiXmlComment& operator=( const TiXmlComment& base );␊ |
␊ |
␉virtual ~TiXmlComment()␉{}␊ |
␊ |
␉/// Returns a copy of this Comment.␊ |
␉virtual TiXmlNode* Clone() const;␊ |
␉// Write this Comment to a FILE stream.␊ |
␉virtual void Print( FILE* cfile, int depth ) const;␊ |
␊ |
␉/*␉Attribtue parsing starts: at the ! of the !--␊ |
␉␉␉␉␉␉ returns: next char past '>'␊ |
␉*/␊ |
␉virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );␊ |
␊ |
␉virtual const TiXmlComment* ToComment() const␉{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␉virtual␉␉ TiXmlComment* ToComment()␉␉{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␊ |
␉/** Walk the XML tree visiting this node and all of its children. ␊ |
␉*/␊ |
␉virtual bool Accept( TiXmlVisitor* visitor ) const;␊ |
␊ |
protected:␊ |
␉void CopyTo( TiXmlComment* target ) const;␊ |
␊ |
␉// used to be public␊ |
␉#ifdef TIXML_USE_STL␊ |
␉virtual void StreamIn( std::istream * in, TIXML_STRING * tag );␊ |
␉#endif␊ |
//␉virtual void StreamOut( TIXML_OSTREAM * out ) const;␊ |
␊ |
private:␊ |
␊ |
};␊ |
␊ |
␊ |
/** XML text. A text node can have 2 ways to output the next. "normal" output ␊ |
␉and CDATA. It will default to the mode it was parsed from the XML file and␊ |
␉you generally want to leave it alone, but you can change the output mode with ␊ |
␉SetCDATA() and query it with CDATA().␊ |
*/␊ |
class TiXmlText : public TiXmlNode␊ |
{␊ |
␉friend class TiXmlElement;␊ |
public:␊ |
␉/** Constructor for text element. By default, it is treated as ␊ |
␉␉normal, encoded text. If you want it be output as a CDATA text␊ |
␉␉element, set the parameter _cdata to 'true'␊ |
␉*/␊ |
␉TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)␊ |
␉{␊ |
␉␉SetValue( initValue );␊ |
␉␉cdata = false;␊ |
␉}␊ |
␉virtual ~TiXmlText() {}␊ |
␊ |
␉#ifdef TIXML_USE_STL␊ |
␉/// Constructor.␊ |
␉TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT)␊ |
␉{␊ |
␉␉SetValue( initValue );␊ |
␉␉cdata = false;␊ |
␉}␊ |
␉#endif␊ |
␊ |
␉TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT )␉{ copy.CopyTo( this ); }␊ |
␉TiXmlText& operator=( const TiXmlText& base )␉␉␉␉␉␉␉ ␉{ base.CopyTo( this ); return *this; }␊ |
␊ |
␉// Write this text object to a FILE stream.␊ |
␉virtual void Print( FILE* cfile, int depth ) const;␊ |
␊ |
␉/// Queries whether this represents text using a CDATA section.␊ |
␉bool CDATA() const␉␉␉␉{ return cdata; }␊ |
␉/// Turns on or off a CDATA representation of text.␊ |
␉void SetCDATA( bool _cdata )␉{ cdata = _cdata; }␊ |
␊ |
␉virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );␊ |
␊ |
␉virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␉virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␊ |
␉/** Walk the XML tree visiting this node and all of its children. ␊ |
␉*/␊ |
␉virtual bool Accept( TiXmlVisitor* content ) const;␊ |
␊ |
protected :␊ |
␉/// [internal use] Creates a new Element and returns it.␊ |
␉virtual TiXmlNode* Clone() const;␊ |
␉void CopyTo( TiXmlText* target ) const;␊ |
␊ |
␉bool Blank() const;␉// returns true if all white space and new lines␊ |
␉// [internal use]␊ |
␉#ifdef TIXML_USE_STL␊ |
␉virtual void StreamIn( std::istream * in, TIXML_STRING * tag );␊ |
␉#endif␊ |
␊ |
private:␊ |
␉bool cdata;␉␉␉// true if this should be input and output as a CDATA style text element␊ |
};␊ |
␊ |
␊ |
/** In correct XML the declaration is the first entry in the file.␊ |
␉@verbatim␊ |
␉␉<?xml version="1.0" standalone="yes"?>␊ |
␉@endverbatim␊ |
␊ |
␉TinyXml will happily read or write files without a declaration,␊ |
␉however. There are 3 possible attributes to the declaration:␊ |
␉version, encoding, and standalone.␊ |
␊ |
␉Note: In this version of the code, the attributes are␊ |
␉handled as special cases, not generic attributes, simply␊ |
␉because there can only be at most 3 and they are always the same.␊ |
*/␊ |
class TiXmlDeclaration : public TiXmlNode␊ |
{␊ |
public:␊ |
␉/// Construct an empty declaration.␊ |
␉TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {}␊ |
␊ |
#ifdef TIXML_USE_STL␊ |
␉/// Constructor.␊ |
␉TiXmlDeclaration(␉const std::string& _version,␊ |
␉␉␉␉␉␉const std::string& _encoding,␊ |
␉␉␉␉␉␉const std::string& _standalone );␊ |
#endif␊ |
␊ |
␉/// Construct.␊ |
␉TiXmlDeclaration(␉const char* _version,␊ |
␉␉␉␉␉␉const char* _encoding,␊ |
␉␉␉␉␉␉const char* _standalone );␊ |
␊ |
␉TiXmlDeclaration( const TiXmlDeclaration& copy );␊ |
␉TiXmlDeclaration& operator=( const TiXmlDeclaration& copy );␊ |
␊ |
␉virtual ~TiXmlDeclaration()␉{}␊ |
␊ |
␉/// Version. Will return an empty string if none was found.␊ |
␉const char *Version() const␉␉␉{ return version.c_str (); }␊ |
␉/// Encoding. Will return an empty string if none was found.␊ |
␉const char *Encoding() const␉␉{ return encoding.c_str (); }␊ |
␉/// Is this a standalone document?␊ |
␉const char *Standalone() const␉␉{ return standalone.c_str (); }␊ |
␊ |
␉/// Creates a copy of this Declaration and returns it.␊ |
␉virtual TiXmlNode* Clone() const;␊ |
␉// Print this declaration to a FILE stream.␊ |
␉virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;␊ |
␉virtual void Print( FILE* cfile, int depth ) const {␊ |
␉␉Print( cfile, depth, 0 );␊ |
␉}␊ |
␊ |
␉virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );␊ |
␊ |
␉virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␉virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␊ |
␉/** Walk the XML tree visiting this node and all of its children. ␊ |
␉*/␊ |
␉virtual bool Accept( TiXmlVisitor* visitor ) const;␊ |
␊ |
protected:␊ |
␉void CopyTo( TiXmlDeclaration* target ) const;␊ |
␉// used to be public␊ |
␉#ifdef TIXML_USE_STL␊ |
␉virtual void StreamIn( std::istream * in, TIXML_STRING * tag );␊ |
␉#endif␊ |
␊ |
private:␊ |
␊ |
␉TIXML_STRING version;␊ |
␉TIXML_STRING encoding;␊ |
␉TIXML_STRING standalone;␊ |
};␊ |
␊ |
␊ |
/** Any tag that tinyXml doesn't recognize is saved as an␊ |
␉unknown. It is a tag of text, but should not be modified.␊ |
␉It will be written back to the XML, unchanged, when the file␊ |
␉is saved.␊ |
␊ |
␉DTD tags get thrown into TiXmlUnknowns.␊ |
*/␊ |
class TiXmlUnknown : public TiXmlNode␊ |
{␊ |
public:␊ |
␉TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )␉{}␊ |
␉virtual ~TiXmlUnknown() {}␊ |
␊ |
␉TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN )␉␉{ copy.CopyTo( this ); }␊ |
␉TiXmlUnknown& operator=( const TiXmlUnknown& copy )␉␉␉␉␉␉␉␉␉␉{ copy.CopyTo( this ); return *this; }␊ |
␊ |
␉/// Creates a copy of this Unknown and returns it.␊ |
␉virtual TiXmlNode* Clone() const;␊ |
␉// Print this Unknown to a FILE stream.␊ |
␉virtual void Print( FILE* cfile, int depth ) const;␊ |
␊ |
␉virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );␊ |
␊ |
␉virtual const TiXmlUnknown* ToUnknown() const␉{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␉virtual TiXmlUnknown* ToUnknown()␉␉␉␉{ return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␊ |
␉/** Walk the XML tree visiting this node and all of its children. ␊ |
␉*/␊ |
␉virtual bool Accept( TiXmlVisitor* content ) const;␊ |
␊ |
protected:␊ |
␉void CopyTo( TiXmlUnknown* target ) const;␊ |
␊ |
␉#ifdef TIXML_USE_STL␊ |
␉virtual void StreamIn( std::istream * in, TIXML_STRING * tag );␊ |
␉#endif␊ |
␊ |
private:␊ |
␊ |
};␊ |
␊ |
␊ |
/** Always the top level node. A document binds together all the␊ |
␉XML pieces. It can be saved, loaded, and printed to the screen.␊ |
␉The 'value' of a document node is the xml file name.␊ |
*/␊ |
class TiXmlDocument : public TiXmlNode␊ |
{␊ |
public:␊ |
␉/// Create an empty document, that has no name.␊ |
␉TiXmlDocument();␊ |
␉/// Create a document with a name. The name of the document is also the filename of the xml.␊ |
␉TiXmlDocument( const char * documentName );␊ |
␊ |
␉#ifdef TIXML_USE_STL␊ |
␉/// Constructor.␊ |
␉TiXmlDocument( const std::string& documentName );␊ |
␉#endif␊ |
␊ |
␉TiXmlDocument( const TiXmlDocument& copy );␊ |
␉TiXmlDocument& operator=( const TiXmlDocument& copy );␊ |
␊ |
␉virtual ~TiXmlDocument() {}␊ |
␊ |
␉/** Load a file using the current document value.␊ |
␉␉Returns true if successful. Will delete any existing␊ |
␉␉document data before loading.␊ |
␉*/␊ |
␉bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );␊ |
␉/// Save a file using the current document value. Returns true if successful.␊ |
␉bool SaveFile() const;␊ |
␉/// Load a file using the given filename. Returns true if successful.␊ |
␉bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );␊ |
␉/// Save a file using the given filename. Returns true if successful.␊ |
␉bool SaveFile( const char * filename ) const;␊ |
␉/** Load a file using the given FILE*. Returns true if successful. Note that this method␊ |
␉␉doesn't stream - the entire object pointed at by the FILE*␊ |
␉␉will be interpreted as an XML file. TinyXML doesn't stream in XML from the current␊ |
␉␉file location. Streaming may be added in the future.␊ |
␉*/␊ |
␉bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );␊ |
␉/// Save a file using the given FILE*. Returns true if successful.␊ |
␉bool SaveFile( FILE* ) const;␊ |
␊ |
␉#ifdef TIXML_USE_STL␊ |
␉bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )␉␉␉///< STL std::string version.␊ |
␉{␊ |
␉␉return LoadFile( filename.c_str(), encoding );␊ |
␉}␊ |
␉bool SaveFile( const std::string& filename ) const␉␉///< STL std::string version.␊ |
␉{␊ |
␉␉return SaveFile( filename.c_str() );␊ |
␉}␊ |
␉#endif␊ |
␊ |
␉/** Parse the given null terminated block of xml data. Passing in an encoding to this␊ |
␉␉method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml␊ |
␉␉to use that encoding, regardless of what TinyXml might otherwise try to detect.␊ |
␉*/␊ |
␉virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );␊ |
␊ |
␉/** Get the root element -- the only top level element -- of the document.␊ |
␉␉In well formed XML, there should only be one. TinyXml is tolerant of␊ |
␉␉multiple elements at the document level.␊ |
␉*/␊ |
␉const TiXmlElement* RootElement() const␉␉{ return FirstChildElement(); }␊ |
␉TiXmlElement* RootElement()␉␉␉␉␉{ return FirstChildElement(); }␊ |
␊ |
␉/** If an error occurs, Error will be set to true. Also,␊ |
␉␉- The ErrorId() will contain the integer identifier of the error (not generally useful)␊ |
␉␉- The ErrorDesc() method will return the name of the error. (very useful)␊ |
␉␉- The ErrorRow() and ErrorCol() will return the location of the error (if known)␊ |
␉*/␉␊ |
␉bool Error() const␉␉␉␉␉␉{ return error; }␊ |
␊ |
␉/// Contains a textual (english) description of the error if one occurs.␊ |
␉const char * ErrorDesc() const␉{ return errorDesc.c_str (); }␊ |
␊ |
␉/** Generally, you probably want the error string ( ErrorDesc() ). But if you␊ |
␉␉prefer the ErrorId, this function will fetch it.␊ |
␉*/␊ |
␉int ErrorId()␉const␉␉␉␉{ return errorId; }␊ |
␊ |
␉/** Returns the location (if known) of the error. The first column is column 1, ␊ |
␉␉and the first row is row 1. A value of 0 means the row and column wasn't applicable␊ |
␉␉(memory errors, for example, have no row/column) or the parser lost the error. (An␊ |
␉␉error in the error reporting, in that case.)␊ |
␊ |
␉␉@sa SetTabSize, Row, Column␊ |
␉*/␊ |
␉int ErrorRow() const␉{ return errorLocation.row+1; }␊ |
␉int ErrorCol() const␉{ return errorLocation.col+1; }␉///< The column where the error occured. See ErrorRow()␊ |
␊ |
␉/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())␊ |
␉␉to report the correct values for row and column. It does not change the output␊ |
␉␉or input in any way.␊ |
␉␉␊ |
␉␉By calling this method, with a tab size␊ |
␉␉greater than 0, the row and column of each node and attribute is stored␊ |
␉␉when the file is loaded. Very useful for tracking the DOM back in to␊ |
␉␉the source file.␊ |
␊ |
␉␉The tab size is required for calculating the location of nodes. If not␊ |
␉␉set, the default of 4 is used. The tabsize is set per document. Setting␊ |
␉␉the tabsize to 0 disables row/column tracking.␊ |
␊ |
␉␉Note that row and column tracking is not supported when using operator>>.␊ |
␊ |
␉␉The tab size needs to be enabled before the parse or load. Correct usage:␊ |
␉␉@verbatim␊ |
␉␉TiXmlDocument doc;␊ |
␉␉doc.SetTabSize( 8 );␊ |
␉␉doc.Load( "myfile.xml" );␊ |
␉␉@endverbatim␊ |
␊ |
␉␉@sa Row, Column␊ |
␉*/␊ |
␉void SetTabSize( int _tabsize )␉␉{ tabsize = _tabsize; }␊ |
␊ |
␉int TabSize() const␉{ return tabsize; }␊ |
␊ |
␉/** If you have handled the error, it can be reset with this call. The error␊ |
␉␉state is automatically cleared if you Parse a new XML block.␊ |
␉*/␊ |
␉void ClearError()␉␉␉␉␉␉{␉error = false; ␊ |
␉␉␉␉␉␉␉␉␉␉␉␉errorId = 0; ␊ |
␉␉␉␉␉␉␉␉␉␉␉␉errorDesc = ""; ␊ |
␉␉␉␉␉␉␉␉␉␉␉␉errorLocation.row = errorLocation.col = 0; ␊ |
␉␉␉␉␉␉␉␉␉␉␉␉//errorLocation.last = 0; ␊ |
␉␉␉␉␉␉␉␉␉␉␉}␊ |
␊ |
␉/** Write the document to standard out using formatted printing ("pretty print"). */␊ |
␉void Print() const␉␉␉␉␉␉{ Print( stdout, 0 ); }␊ |
␊ |
␉/* Write the document to a string using formatted printing ("pretty print"). This␊ |
␉␉will allocate a character array (new char[]) and return it as a pointer. The␊ |
␉␉calling code pust call delete[] on the return char* to avoid a memory leak.␊ |
␉*/␊ |
␉//char* PrintToMemory() const; ␊ |
␊ |
␉/// Print this Document to a FILE stream.␊ |
␉virtual void Print( FILE* cfile, int depth = 0 ) const;␊ |
␉// [internal use]␊ |
␉void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );␊ |
␊ |
␉virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␉virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.␊ |
␊ |
␉/** Walk the XML tree visiting this node and all of its children. ␊ |
␉*/␊ |
␉virtual bool Accept( TiXmlVisitor* content ) const;␊ |
␊ |
protected :␊ |
␉// [internal use]␊ |
␉virtual TiXmlNode* Clone() const;␊ |
␉#ifdef TIXML_USE_STL␊ |
␉virtual void StreamIn( std::istream * in, TIXML_STRING * tag );␊ |
␉#endif␊ |
␊ |
private:␊ |
␉void CopyTo( TiXmlDocument* target ) const;␊ |
␊ |
␉bool error;␊ |
␉int errorId;␊ |
␉TIXML_STRING errorDesc;␊ |
␉int tabsize;␊ |
␉TiXmlCursor errorLocation;␊ |
␉bool useMicrosoftBOM;␉␉// the UTF-8 BOM were found when read. Note this, and try to write.␊ |
};␊ |
␊ |
␊ |
/**␊ |
␉A TiXmlHandle is a class that wraps a node pointer with null checks; this is␊ |
␉an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml␊ |
␉DOM structure. It is a separate utility class.␊ |
␊ |
␉Take an example:␊ |
␉@verbatim␊ |
␉<Document>␊ |
␉␉<Element attributeA = "valueA">␊ |
␉␉␉<Child attributeB = "value1" />␊ |
␉␉␉<Child attributeB = "value2" />␊ |
␉␉</Element>␊ |
␉<Document>␊ |
␉@endverbatim␊ |
␊ |
␉Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very ␊ |
␉easy to write a *lot* of code that looks like:␊ |
␊ |
␉@verbatim␊ |
␉TiXmlElement* root = document.FirstChildElement( "Document" );␊ |
␉if ( root )␊ |
␉{␊ |
␉␉TiXmlElement* element = root->FirstChildElement( "Element" );␊ |
␉␉if ( element )␊ |
␉␉{␊ |
␉␉␉TiXmlElement* child = element->FirstChildElement( "Child" );␊ |
␉␉␉if ( child )␊ |
␉␉␉{␊ |
␉␉␉␉TiXmlElement* child2 = child->NextSiblingElement( "Child" );␊ |
␉␉␉␉if ( child2 )␊ |
␉␉␉␉{␊ |
␉␉␉␉␉// Finally do something useful.␊ |
␉@endverbatim␊ |
␊ |
␉And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity␊ |
␉of such code. A TiXmlHandle checks for null␉pointers so it is perfectly safe ␊ |
␉and correct to use:␊ |
␊ |
␉@verbatim␊ |
␉TiXmlHandle docHandle( &document );␊ |
␉TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();␊ |
␉if ( child2 )␊ |
␉{␊ |
␉␉// do something useful␊ |
␉@endverbatim␊ |
␊ |
␉Which is MUCH more concise and useful.␊ |
␊ |
␉It is also safe to copy handles - internally they are nothing more than node pointers.␊ |
␉@verbatim␊ |
␉TiXmlHandle handleCopy = handle;␊ |
␉@endverbatim␊ |
␊ |
␉What they should not be used for is iteration:␊ |
␊ |
␉@verbatim␊ |
␉int i=0; ␊ |
␉while ( true )␊ |
␉{␊ |
␉␉TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();␊ |
␉␉if ( !child )␊ |
␉␉␉break;␊ |
␉␉// do something␊ |
␉␉++i;␊ |
␉}␊ |
␉@endverbatim␊ |
␊ |
␉It seems reasonable, but it is in fact two embedded while loops. The Child method is ␊ |
␉a linear walk to find the element, so this code would iterate much more than it needs ␊ |
␉to. Instead, prefer:␊ |
␊ |
␉@verbatim␊ |
␉TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();␊ |
␊ |
␉for( child; child; child=child->NextSiblingElement() )␊ |
␉{␊ |
␉␉// do something␊ |
␉}␊ |
␉@endverbatim␊ |
*/␊ |
class TiXmlHandle␊ |
{␊ |
public:␊ |
␉/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.␊ |
␉TiXmlHandle( TiXmlNode* _node )␉␉␉␉␉{ this->node = _node; }␊ |
␉/// Copy constructor␊ |
␉TiXmlHandle( const TiXmlHandle& ref )␉␉␉{ this->node = ref.node; }␊ |
␉TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; }␊ |
␊ |
␉/// Return a handle to the first child node.␊ |
␉TiXmlHandle FirstChild() const;␊ |
␉/// Return a handle to the first child node with the given name.␊ |
␉TiXmlHandle FirstChild( const char * value ) const;␊ |
␉/// Return a handle to the first child element.␊ |
␉TiXmlHandle FirstChildElement() const;␊ |
␉/// Return a handle to the first child element with the given name.␊ |
␉TiXmlHandle FirstChildElement( const char * value ) const;␊ |
␊ |
␉/** Return a handle to the "index" child with the given name. ␊ |
␉␉The first child is 0, the second 1, etc.␊ |
␉*/␊ |
␉TiXmlHandle Child( const char* value, int index ) const;␊ |
␉/** Return a handle to the "index" child. ␊ |
␉␉The first child is 0, the second 1, etc.␊ |
␉*/␊ |
␉TiXmlHandle Child( int index ) const;␊ |
␉/** Return a handle to the "index" child element with the given name. ␊ |
␉␉The first child element is 0, the second 1, etc. Note that only TiXmlElements␊ |
␉␉are indexed: other types are not counted.␊ |
␉*/␊ |
␉TiXmlHandle ChildElement( const char* value, int index ) const;␊ |
␉/** Return a handle to the "index" child element. ␊ |
␉␉The first child element is 0, the second 1, etc. Note that only TiXmlElements␊ |
␉␉are indexed: other types are not counted.␊ |
␉*/␊ |
␉TiXmlHandle ChildElement( int index ) const;␊ |
␊ |
␉#ifdef TIXML_USE_STL␊ |
␉TiXmlHandle FirstChild( const std::string& _value ) const␉␉␉␉{ return FirstChild( _value.c_str() ); }␊ |
␉TiXmlHandle FirstChildElement( const std::string& _value ) const␉␉{ return FirstChildElement( _value.c_str() ); }␊ |
␊ |
␉TiXmlHandle Child( const std::string& _value, int index ) const␉␉␉{ return Child( _value.c_str(), index ); }␊ |
␉TiXmlHandle ChildElement( const std::string& _value, int index ) const␉{ return ChildElement( _value.c_str(), index ); }␊ |
␉#endif␊ |
␊ |
␉/** Return the handle as a TiXmlNode. This may return null.␊ |
␉*/␊ |
␉TiXmlNode* ToNode() const␉␉␉{ return node; } ␊ |
␉/** Return the handle as a TiXmlElement. This may return null.␊ |
␉*/␊ |
␉TiXmlElement* ToElement() const␉␉{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }␊ |
␉/**␉Return the handle as a TiXmlText. This may return null.␊ |
␉*/␊ |
␉TiXmlText* ToText() const␉␉␉{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }␊ |
␉/** Return the handle as a TiXmlUnknown. This may return null.␊ |
␉*/␊ |
␉TiXmlUnknown* ToUnknown() const␉␉{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }␊ |
␊ |
␉/** @deprecated use ToNode. ␊ |
␉␉Return the handle as a TiXmlNode. This may return null.␊ |
␉*/␊ |
␉TiXmlNode* Node() const␉␉␉{ return ToNode(); } ␊ |
␉/** @deprecated use ToElement. ␊ |
␉␉Return the handle as a TiXmlElement. This may return null.␊ |
␉*/␊ |
␉TiXmlElement* Element() const␉{ return ToElement(); }␊ |
␉/**␉@deprecated use ToText()␊ |
␉␉Return the handle as a TiXmlText. This may return null.␊ |
␉*/␊ |
␉TiXmlText* Text() const␉␉␉{ return ToText(); }␊ |
␉/** @deprecated use ToUnknown()␊ |
␉␉Return the handle as a TiXmlUnknown. This may return null.␊ |
␉*/␊ |
␉TiXmlUnknown* Unknown() const␉{ return ToUnknown(); }␊ |
␊ |
private:␊ |
␉TiXmlNode* node;␊ |
};␊ |
␊ |
␊ |
/** Print to memory functionality. The TiXmlPrinter is useful when you need to:␊ |
␊ |
␉-# Print to memory (especially in non-STL mode)␊ |
␉-# Control formatting (line endings, etc.)␊ |
␊ |
␉When constructed, the TiXmlPrinter is in its default "pretty printing" mode.␊ |
␉Before calling Accept() you can call methods to control the printing␊ |
␉of the XML document. After TiXmlNode::Accept() is called, the printed document can␊ |
␉be accessed via the CStr(), Str(), and Size() methods.␊ |
␊ |
␉TiXmlPrinter uses the Visitor API.␊ |
␉@verbatim␊ |
␉TiXmlPrinter printer;␊ |
␉printer.SetIndent( "\t" );␊ |
␊ |
␉doc.Accept( &printer );␊ |
␉fprintf( stdout, "%s", printer.CStr() );␊ |
␉@endverbatim␊ |
*/␊ |
class TiXmlPrinter : public TiXmlVisitor␊ |
{␊ |
public:␊ |
␉TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),␊ |
␉␉␉␉␉ buffer(), indent( " " ), lineBreak( "\n" ) {}␊ |
␊ |
␉virtual bool VisitEnter( const TiXmlDocument& doc );␊ |
␉virtual bool VisitExit( const TiXmlDocument& doc );␊ |
␊ |
␉virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );␊ |
␉virtual bool VisitExit( const TiXmlElement& element );␊ |
␊ |
␉virtual bool Visit( const TiXmlDeclaration& declaration );␊ |
␉virtual bool Visit( const TiXmlText& text );␊ |
␉virtual bool Visit( const TiXmlComment& comment );␊ |
␉virtual bool Visit( const TiXmlUnknown& unknown );␊ |
␊ |
␉/** Set the indent characters for printing. By default 4 spaces␊ |
␉␉but tab (\t) is also useful, or null/empty string for no indentation.␊ |
␉*/␊ |
␉void SetIndent( const char* _indent )␉␉␉{ indent = _indent ? _indent : "" ; }␊ |
␉/// Query the indention string.␊ |
␉const char* Indent()␉␉␉␉␉␉␉{ return indent.c_str(); }␊ |
␉/** Set the line breaking string. By default set to newline (\n). ␊ |
␉␉Some operating systems prefer other characters, or can be␊ |
␉␉set to the null/empty string for no indenation.␊ |
␉*/␊ |
␉void SetLineBreak( const char* _lineBreak )␉␉{ lineBreak = _lineBreak ? _lineBreak : ""; }␊ |
␉/// Query the current line breaking string.␊ |
␉const char* LineBreak()␉␉␉␉␉␉␉{ return lineBreak.c_str(); }␊ |
␊ |
␉/** Switch over to "stream printing" which is the most dense formatting without ␊ |
␉␉linebreaks. Common when the XML is needed for network transmission.␊ |
␉*/␊ |
␉void SetStreamPrinting()␉␉␉␉␉␉{ indent = "";␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␉ lineBreak = "";␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␉}␉␊ |
␉/// Return the result.␊ |
␉const char* CStr()␉␉␉␉␉␉␉␉{ return buffer.c_str(); }␊ |
␉/// Return the length of the result string.␊ |
␉size_t Size()␉␉␉␉␉␉␉␉␉{ return buffer.size(); }␊ |
␊ |
␉#ifdef TIXML_USE_STL␊ |
␉/// Return the result.␊ |
␉const std::string& Str()␉␉␉␉␉␉{ return buffer; }␊ |
␉#endif␊ |
␊ |
private:␊ |
␉void DoIndent()␉{␊ |
␉␉for( int i=0; i<depth; ++i )␊ |
␉␉␉buffer += indent;␊ |
␉}␊ |
␉void DoLineBreak() {␊ |
␉␉buffer += lineBreak;␊ |
␉}␊ |
␊ |
␉int depth;␊ |
␉bool simpleTextPrint;␊ |
␉TIXML_STRING buffer;␊ |
␉TIXML_STRING indent;␊ |
␉TIXML_STRING lineBreak;␊ |
};␊ |
␊ |
␊ |
#ifdef _MSC_VER␊ |
#pragma warning( pop )␊ |
#endif␊ |
␊ |
#endif␊ |