tinyxml.h   tinyxml.h 
/* /*
Copyright (c) 2000 Lee Thomason (www.grinninglizard.com) www.sourceforge.net/projects/tinyxml
Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.g
rinninglizard.com)
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any warranty. In no event will the authors be held liable for any
damages arising from the use of this software. damages arising from the use of this software.
Permission is granted to anyone to use this software for any Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions: redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must 1. The origin of this software must not be misrepresented; you must
skipping to change at line 30 skipping to change at line 31
3. This notice may not be removed or altered from any source 3. This notice may not be removed or altered from any source
distribution. distribution.
*/ */
#ifndef TINYXML_INCLUDED #ifndef TINYXML_INCLUDED
#define TINYXML_INCLUDED #define TINYXML_INCLUDED
#pragma warning( disable : 4530 ) #pragma warning( disable : 4530 )
#pragma warning( disable : 4786 ) #pragma warning( disable : 4786 )
#include <string> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <assert.h>
// Help out windows:
#if defined( _DEBUG ) && !defined( DEBUG )
#define DEBUG
#endif
#if defined( DEBUG ) && defined( _MSC_VER )
#include <windows.h>
#define TIXML_LOG OutputDebugString
#else
#define TIXML_LOG printf
#endif
#ifdef TIXML_USE_STL
#include <string>
#define TIXML_STRING std::string
#define TIXML_ISTREAM std::istream
#define TIXML_OSTREAM std::ostream
#else
#include "tinystr.h"
#define TIXML_STRING TiXmlString
#define TIXML_OSTREAM TiXmlOutStream
#endif
class TiXmlDocument; class TiXmlDocument;
class TiXmlElement; class TiXmlElement;
class TiXmlComment; class TiXmlComment;
class TiXmlUnknown; class TiXmlUnknown;
class TiXmlAttribute; class TiXmlAttribute;
class TiXmlText; class TiXmlText;
class TiXmlDeclaration; class TiXmlDeclaration;
/** TiXmlBase is a base class for every class in TinyXml. /** TiXmlBase is a base class for every class in TinyXml.
It does little except to establist that TinyXml classes It does little except to establish that TinyXml classes
can be printed and provide some utility functions. can be printed and provide some utility functions.
In XML, the document and elements can contain In XML, the document and elements can contain
other elements and other types of nodes. other elements and other types of nodes.
@verbatim @verbatim
A Document can contain: Element (container or leaf) A Document can contain: Element (container or leaf)
Comment (leaf) Comment (leaf)
Unknown (leaf) Unknown (leaf)
Declaration( leaf ) Declaration( leaf )
skipping to change at line 72 skipping to change at line 96
A Decleration contains: Attributes (not on tree) A Decleration contains: Attributes (not on tree)
@endverbatim @endverbatim
*/ */
class TiXmlBase class TiXmlBase
{ {
friend class TiXmlNode; friend class TiXmlNode;
friend class TiXmlElement; friend class TiXmlElement;
friend class TiXmlDocument; friend class TiXmlDocument;
public: public:
TiXmlBase() {} TiXmlBase() {}
virtual ~TiXmlBase() {} virtual ~TiXmlBase() {}
/* All TinyXml classes can print themselves to a filestream. /** All TinyXml classes can print themselves to a filestream.
This is a formatted print, and will insert tabs and newlines
.
(For an unformatted stream, use the << operator.)
*/ */
virtual void Print( FILE* fp, int depth ) = 0; virtual void Print( FILE* cfile, int depth ) const = 0;
protected: /** The world does not agree on whether white space should be ke
/* General parsing helper method. Takes a pointer in, pt or
skips all the white space it finds, and returns a pointer not. In order to make everyone happy, these global, static f
to the first non-whitespace data. unctions
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 these
values is not thread safe.
*/ */
static const char* SkipWhiteSpace( const char* p ); static void SetCondenseWhiteSpace( bool condense ) { co
ndenseWhiteSpace = condense; }
/// Return the current white space setting.
static bool IsWhiteSpaceCondensed()
{ return condenseWhiteSpace; }
protected:
static const char* SkipWhiteSpace( const char* );
inline static bool IsWhiteSpace( int c ) { return ( i
sspace( c ) || c == '\n' || c == '\r' ); }
virtual void StreamOut (TIXML_OSTREAM *) const = 0;
#ifdef TIXML_USE_STL
static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING *
tag );
static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_S
TRING * tag );
#endif
/* Reads an XML name into the string provided. Returns /* Reads an XML name into the string provided. Returns
a pointer just past the last character of the name, a pointer just past the last character of the name,
or 0 if the function has an error. or 0 if the function has an error.
*/ */
static const char* ReadName( const char* p, std::string* name ); static const char* ReadName( const char* p, TIXML_STRING* name );
/* 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
TIXM
L_STRING* text, // the string read
bool
ignoreWhiteSpace, // whether to keep the white space
cons
t char* endTag, // what ends this text
bool
ignoreCase ); // whether to ignore case in the end ta
g
virtual const char* Parse( const char* p ) = 0;
// If an entity has been found, transform it into a character.
static const char* GetEntity( const char* in, char* value );
// Get a character, while interpreting entities.
inline static const char* GetChar( const char* p, char* value )
{
assert( p );
if ( *p == '&' )
{
return GetEntity( p, value );
}
else
{
*value = *p;
return p+1;
}
}
// Puts a string to a stream, expanding entities as it goes.
// Note this should not contian the '<', '>', etc, or they will be t
ransformed into entities!
static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out )
;
static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
// Return true if the next characters in the stream are any of the e
ndTag sequences.
bool static StringEqual( const char* p,
const char*
endTag,
bool ignoreC
ase );
enum enum
{ {
TIXML_NO_ERROR = 0, TIXML_NO_ERROR = 0,
TIXML_ERROR,
TIXML_ERROR_OPENING_FILE, TIXML_ERROR_OPENING_FILE,
TIXML_ERROR_OUT_OF_MEMORY, TIXML_ERROR_OUT_OF_MEMORY,
TIXML_ERROR_PARSING_ELEMENT, TIXML_ERROR_PARSING_ELEMENT,
TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
TIXML_ERROR_READING_ELEMENT_VALUE, TIXML_ERROR_READING_ELEMENT_VALUE,
TIXML_ERROR_READING_ATTRIBUTES, TIXML_ERROR_READING_ATTRIBUTES,
TIXML_ERROR_PARSING_EMPTY, TIXML_ERROR_PARSING_EMPTY,
TIXML_ERROR_READING_END_TAG, TIXML_ERROR_READING_END_TAG,
TIXML_ERROR_PARSING_UNKNOWN, TIXML_ERROR_PARSING_UNKNOWN,
TIXML_ERROR_PARSING_COMMENT, TIXML_ERROR_PARSING_COMMENT,
TIXML_ERROR_PARSING_DECLARATION, TIXML_ERROR_PARSING_DECLARATION,
TIXML_ERROR_DOCUMENT_EMPTY,
TIXML_ERROR_STRING_COUNT TIXML_ERROR_STRING_COUNT
}; };
static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
private:
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. /** The parent class for everything in the Document Object Model.
(Except for attributes, which are contained in elements.) (Except for attributes, which are contained in elements.)
Nodes have siblings, a parent, and children. A node can be Nodes have siblings, a parent, and children. A node can be
in a document, or stand on its own. The type of a TyXmlNode 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. can be queried, and it can be cast to its more defined type.
*/ */
class TiXmlNode : public TiXmlBase class TiXmlNode : public TiXmlBase
{ {
public: friend class TiXmlDocument;
friend class TiXmlElement;
public:
#ifdef TIXML_USE_STL
/** An input stream operator, for every class. Tolerant of newli
nes and
formatting, but doesn't expect them.
*/
friend std::istream& operator >> (std::istream& in, TiXmlNode& b
ase);
/** An output stream operator, for every class. Note that this o
utputs
without any newlines or formatting, as opposed to Print(
), which
includes tabs and new lines.
The operator<< and operator>> are not completely symmetr
ic. Writing
a node to a stream is very well defined. You'll get a ni
ce stream
of output, without any extra whitespace or newlines.
But reading is not as well defined. (As it always is.) I
f 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 min
d.
A TiXmlDocument will read nodes until it reads a root el
ement.
*/
friend std::ostream & operator<< (std::ostream& out, const TiXml
Node& base);
#else
// Used internally, not part of the public API.
friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXm
lNode& base);
#endif
/** The types of XML nodes supported by TinyXml. (All the /** The types of XML nodes supported by TinyXml. (All the
unsupported types are picked up by UNKNOWN.) unsupported types are picked up by UNKNOWN.)
*/ */
enum NodeType enum NodeType
{ {
DOCUMENT, ELEMENT, COMMENT, UNKNOWN, TEXT, DECLARATION, TYPE DOCUMENT,
COUNT ELEMENT,
COMMENT,
UNKNOWN,
TEXT,
DECLARATION,
TYPECOUNT
}; };
virtual ~TiXmlNode(); virtual ~TiXmlNode();
/** The meaning of 'value' changes for the specific type of /** The meaning of 'value' changes for the specific type of
TiXmlNode. TiXmlNode.
@verbatim @verbatim
Document: filename of the xml file Document: filename of the xml file
Element: name of the element Element: name of the element
Comment: the comment text Comment: the comment text
Unknown: the tag contents Unknown: the tag contents
Text: the text string Text: the text string
@endverbatim @endverbatim
The subclasses will wrap this function. The subclasses will wrap this function.
*/ */
const std::string& Value() const { return val ue; } const char * Value () const { return value.c_str (); }
/** Changes the value of the node. Defined as: /** Changes the value of the node. Defined as:
@verbatim @verbatim
Document: filename of the xml file Document: filename of the xml file
Element: name of the element Element: name of the element
Comment: the comment text Comment: the comment text
Unknown: the tag contents Unknown: the tag contents
Text: the text string Text: the text string
@endverbatim @endverbatim
*/ */
void SetValue( const std::string& _value ) { value = _v void SetValue (const char * _value) { value = _value;}
alue; }
#ifdef TIXML_USE_STL
void SetValue( const std::string& value ) { SetValue (value .
c_str ()); } ///< STL std::string form.
#endif
/// Delete all the children of this node. Does not affect 'this'. /// Delete all the children of this node. Does not affect 'this'.
void Clear(); void Clear();
/// One step up the DOM. /// One step up the DOM.
TiXmlNode* Parent() const { re turn parent; } TiXmlNode* Parent() const { re turn parent; }
TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children.
TiXmlNode* FirstChild( const std::string& value ) const; ///< The first child of this node with the matching 'value'. Will be null if no ne found. TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be nu ll if none found.
TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children.
TiXmlNode* LastChild( const std::string& value ) const; /// TiXmlNode* LastChild( const char * value ) const;
The last child of this node matching 'value'. Will be null if there are no /// The last child of this node matching 'value'. Will be null if there
children. are no children.
#ifdef TIXML_USE_STL
TiXmlNode* FirstChild( const std::string& value ) const { retu
rn FirstChild (value . c_str ()); } ///< STL std::string form.
TiXmlNode* LastChild( const std::string& value ) const { retu
rn LastChild (value . c_str ()); } ///< STL std::string form.
#endif
/** An alternate way to walk the children of a node. /** An alternate way to walk the children of a node.
One way to iterate over nodes is: One way to iterate over nodes is:
@verbatim @verbatim
for( child = parent->FirstChild(); child; child = ch ild->NextSibling() ) for( child = parent->FirstChild(); child; child = ch ild->NextSibling() )
@endverbatim @endverbatim
IterateChildren does the same thing with the syntax: IterateChildren does the same thing with the syntax:
@verbatim @verbatim
child = 0; child = 0;
while( child = parent->IterateChildren( child ) ) while( child = parent->IterateChildren( child ) )
@endverbatim @endverbatim
IterateChildren takes the previous child as input and finds IterateChildren takes the previous child as input and finds
the next one. If the previous child is null, it returns the the next one. If the previous child is null, it returns the
first. IterateChildren will return null when done. first. IterateChildren will return null when done.
*/ */
TiXmlNode* IterateChildren( TiXmlNode* previous ); TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
/// This flavor of IterateChildren searches for children with a part icular 'value' /// This flavor of IterateChildren searches for children with a part icular 'value'
TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* pre TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous
vious ); ) const;
#ifdef TIXML_USE_STL
TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* pre
vious ) const { return IterateChildren (value . c_str (), previ
ous); } ///< STL std::string form.
#endif
/** Add a new node related to this. Adds a child past the LastChild. /** 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 occu red. Returns a pointer to the new object or NULL if an error occu red.
*/ */
TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
/** Add a new node related to this. Adds a child before the specifie d child. /** Add a new node related to this. Adds a child before the specifie d child.
Returns a pointer to the new object or NULL if an error occu red. Returns a pointer to the new object or NULL if an error occu red.
*/ */
TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode & addThis ); TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode & addThis );
skipping to change at line 217 skipping to change at line 368
*/ */
TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& wi thThis ); TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& wi thThis );
/// Delete a child of this node. /// Delete a child of this node.
bool RemoveChild( TiXmlNode* removeThis ); bool RemoveChild( TiXmlNode* removeThis );
/// Navigate to a sibling node. /// Navigate to a sibling node.
TiXmlNode* PreviousSibling() const { return pre v; } TiXmlNode* PreviousSibling() const { return pre v; }
/// Navigate to a sibling node. /// Navigate to a sibling node.
TiXmlNode* PreviousSibling( const std::string& ) const; TiXmlNode* PreviousSibling( const char * ) const;
#ifdef TIXML_USE_STL
TiXmlNode* PreviousSibling( const std::string& value ) const {
return PreviousSibling (value . c_str ()); } ///< STL std::s
tring form.
TiXmlNode* NextSibling( const std::string& value) const { retu
rn NextSibling (value . c_str ()); } ///< STL std::string form.
#endif
/// Navigate to a sibling node. /// Navigate to a sibling node.
TiXmlNode* NextSibling() const { return nex t; } TiXmlNode* NextSibling() const { return nex t; }
/// Navigate to a sibling node with the given 'value'. /// Navigate to a sibling node with the given 'value'.
TiXmlNode* NextSibling( const std::string& ) const; TiXmlNode* NextSibling( const char * ) const;
/** Convenience function to get through elements. /** Convenience function to get through elements.
Calls NextSibling and ToElement. Will skip all non-Element Calls NextSibling and ToElement. Will skip all non-Element
nodes. Returns 0 if there is not another element. nodes. Returns 0 if there is not another element.
*/ */
TiXmlElement* NextSiblingElement() const; TiXmlElement* NextSiblingElement() const;
/** Convenience function to get through elements. /** Convenience function to get through elements.
Calls NextSibling and ToElement. Will skip all non-Element Calls NextSibling and ToElement. Will skip all non-Element
nodes. Returns 0 if there is not another element. nodes. Returns 0 if there is not another element.
*/ */
TiXmlElement* NextSiblingElement( const std::string& ) const; TiXmlElement* NextSiblingElement( const char * ) const;
#ifdef TIXML_USE_STL
TiXmlElement* NextSiblingElement( const std::string& value) const
{ return NextSiblingElement (value . c_str ()); } ///< ST
L std::string form.
#endif
/// Convenience function to get through elements. /// Convenience function to get through elements.
TiXmlElement* FirstChildElement() const; TiXmlElement* FirstChildElement() const;
/// Convenience function to get through elements. /// Convenience function to get through elements.
TiXmlElement* FirstChildElement( const std::string& value ) const; TiXmlElement* FirstChildElement( const char * value ) const;
#ifdef TIXML_USE_STL
TiXmlElement* FirstChildElement( const std::string& value ) const
{ return FirstChildElement (value . c_str ()); } ///< ST
L std::string form.
#endif
/// Query the type (as an enumerated value, above) of this node. /// Query the type (as an enumerated value, above) of this node.
virtual int Type() { return type; } virtual int Type() const { return type; }
/** Return a pointer to the Document this node lives in. /** Return a pointer to the Document this node lives in.
Returns null if not in a document. Returns null if not in a document.
*/ */
TiXmlDocument* GetDocument() const; TiXmlDocument* GetDocument() const;
TiXmlDocument* ToDocument() const { return ( type == DOCUMENT /// Returns true if this node has no children.
) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will ret bool NoChildren() const { re
urn null not of the requested type. turn !firstChild; }
TiXmlElement* ToElement() const { return ( type == ELEMENT
) ? (TiXmlElement*) this : 0; } ///< Cast to a more defined type. Will ret TiXmlDocument* ToDocument() const { return ( this && t
urn null not of the requested type. ype == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more define
TiXmlComment* ToComment() const { return ( type == COMMENT d type. Will return null not of the requested type.
) ? (TiXmlComment*) this : 0; } ///< Cast to a more defined type. Will ret TiXmlElement* ToElement() const { return ( this && t
urn null not of the requested type. ype == ELEMENT ) ? (TiXmlElement*) this : 0; } ///< Cast to a more define
TiXmlUnknown* ToUnknown() const { return ( type == UNKNOWN d type. Will return null not of the requested type.
) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more defined type. Will ret TiXmlComment* ToComment() const { return ( this && t
urn null not of the requested type. ype == COMMENT ) ? (TiXmlComment*) this : 0; } ///< Cast to a more define
TiXmlText* ToText() const { return ( type == TEXT d type. Will return null not of the requested type.
) ? (TiXmlText*) this : 0; } ///< Cast to a more defined type. Will ret TiXmlUnknown* ToUnknown() const { return ( this && t
urn null not of the requested type. ype == UNKNOWN ) ? (TiXmlUnknown*) this : 0; } ///< Cast to a more define
TiXmlDeclaration* ToDeclaration() const { return ( type == DECLARATI d type. Will return null not of the requested type.
ON ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Wi TiXmlText* ToText() const { return ( this && t
ll return null not of the requested type. ype == TEXT ) ? (TiXmlText*) this : 0; } ///< Cast to a more define
d type. Will return null not of the requested type.
TiXmlDeclaration* ToDeclaration() const { return ( this && type == D
ECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined
type. Will return null not of the requested type.
virtual TiXmlNode* Clone() const = 0; virtual TiXmlNode* Clone() const = 0;
protected: protected:
TiXmlNode( NodeType type ); TiXmlNode( NodeType type );
virtual const char* Parse( const char* ) = 0;
#ifdef TIXML_USE_STL
// The real work of the input operator.
virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) =
0;
#endif
// The node is passed in by ownership. This object will delete it. // The node is passed in by ownership. This object will delete it.
TiXmlNode* LinkEndChild( TiXmlNode* addThis ); TiXmlNode* LinkEndChild( TiXmlNode* addThis );
// Figure out what is at *p, and parse it. Return a node if // Figure out what is at *p, and parse it. Returns null if it is not
// successful, and update p. an xml node.
TiXmlNode* IdentifyAndParse( const char** p ); TiXmlNode* Identify( const char* start );
void CopyToClone( TiXmlNode* target ) const { target->SetValue (
value.c_str() ); }
void CopyToClone( TiXmlNode* target ) const { target->value = va // Internal Value function returning a TIXML_STRING
lue; } TIXML_STRING SValue() const { return value ; }
TiXmlNode* parent; TiXmlNode* parent;
NodeType type; NodeType type;
TiXmlNode* firstChild; TiXmlNode* firstChild;
TiXmlNode* lastChild; TiXmlNode* lastChild;
std::string value; TIXML_STRING value;
TiXmlNode* prev; TiXmlNode* prev;
TiXmlNode* next; TiXmlNode* next;
}; };
/** An attribute is a name-value pair. Elements have an arbitrary /** An attribute is a name-value pair. Elements have an arbitrary
number of attributes, each with a unique name. number of attributes, each with a unique name.
@note The attributes are not TiXmlNodes, since they are not @note The attributes are not TiXmlNodes, since they are not
part of the tinyXML document object model. There are other part of the tinyXML document object model. There are other
suggested ways to look at this problem. suggested ways to look at this problem.
@note Attributes have a parent @note Attributes have a parent
*/ */
class TiXmlAttribute : public TiXmlBase class TiXmlAttribute : public TiXmlBase
{ {
friend class TiXmlAttributeSet; friend class TiXmlAttributeSet;
public: public:
/// Construct an empty attribute. /// Construct an empty attribute.
TiXmlAttribute() : prev( 0 ), next( 0 ) {} TiXmlAttribute() : prev( 0 ), next( 0 ) {}
#ifdef TIXML_USE_STL
/// std::string constructor.
TiXmlAttribute( const std::string& _name, const std::string& _value
)
{
name = _name . c_str ();
value = _value . c_str ();
}
#endif
/// Construct an attribute with a name and value. /// Construct an attribute with a name and value.
TiXmlAttribute( const std::string& _name, const std::string& _value TiXmlAttribute( const char * _name, const char * _value ): name( _na
) : name( _name ), value( _value ), prev( 0 ), next( 0 ) {} me ), value( _value ), prev( 0 ), 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.
const int IntValue() const;
///< Return the value of this attribute
, converted to an integer.
const double DoubleValue() const;
///< Return the value of this attribute, conver
ted to a double.
const std::string& Name() const { return name; } ///< void SetName( const char* _name ) { name = _name; }
Return the name of this attribute. ///< Set the name of this attribute.
const std::string& Value() const { return value; } ///< void SetValue( const char* _value ) { value = _value; }
Return the value of this attribute. ///< Set the value.
void SetName( const std::string& _name ) { name = _name; } void SetIntValue( int value );
///< Set the name of this attribute. ///< Set the value from an integer.
void SetValue( const std::string& _value ) { value = _value; } void SetDoubleValue( double value );
///< Set the value. ///< Set the value from a double.
#ifdef TIXML_USE_STL
void SetName( const std::string& _name ) { SetName (_na
me . c_str ()); } ///< STL std::string form.
void SetValue( const std::string& _value ) { SetValue (_v
alue . c_str ()); } ///< STL std::string form.
#endif
/// Get the next sibling attribute in the DOM. Returns null at end. /// Get the next sibling attribute in the DOM. Returns null at end.
TiXmlAttribute* Next(); TiXmlAttribute* Next() const;
/// Get the previous sibling attribute in the DOM. Returns null at b eginning. /// Get the previous sibling attribute in the DOM. Returns null at b eginning.
TiXmlAttribute* Previous(); TiXmlAttribute* Previous() const;
bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } 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; }
bool operator>( const TiXmlAttribute& rhs ) const { return name > r hs.name; } bool operator>( const TiXmlAttribute& rhs ) const { return name > r hs.name; }
/* [internal use] /* [internal use]
Attribtue parsing starts: first letter of the name Attribtue parsing starts: first letter of the name
returns: the next char afte r the value end quote returns: the next char afte r the value end quote
*/ */
const char* Parse( const char* ); virtual const char* Parse( const char* p );
// [internal use] // [internal use]
virtual void Print( FILE* fp, int depth ); virtual void Print( FILE* cfile, int depth ) const;
virtual void StreamOut( TIXML_OSTREAM * out ) const;
// [internal use] // [internal use]
// Set the document pointer so the attribute can report errors. // Set the document pointer so the attribute can report errors.
void SetDocument( TiXmlDocument* doc ) { document = doc; } void SetDocument( TiXmlDocument* doc ) { document = doc; }
private: private:
TiXmlDocument* document; // A pointer back to a document, for error reporting. TiXmlDocument* document; // A pointer back to a document, for error reporting.
std::string name; TIXML_STRING name;
std::string value; TIXML_STRING value;
TiXmlAttribute* prev; TiXmlAttribute* prev;
TiXmlAttribute* next; TiXmlAttribute* next;
}; };
/* A class used to manage a group of attributes. /* A class used to manage a group of attributes.
It is only used internally, both by the ELEMENT and the DECLARATION. It is only used internally, both by the ELEMENT and the DECLARATION.
The set can be changed transparent to the Element and Declaration The set can be changed transparent to the Element and Declaration
classes that use it, but NOT transparent to the Attribute classes that use it, but NOT transparent to the Attribute
which has to implement a next() and previous() method. Which makes which has to implement a next() and previous() method. Which makes
it a bit problematic and prevents the use of STL. it a bit problematic and prevents the use of STL.
This version is implemented with circular lists because: This version is implemented with circular lists because:
- I like circular lists - I like circular lists
- it demonstrates some independence from the (typical) doubl y linked list. - it demonstrates some independence from the (typical) doubl y linked list.
*/ */
class TiXmlAttributeSet class TiXmlAttributeSet
{ {
public: public:
TiXmlAttributeSet(); TiXmlAttributeSet();
~TiXmlAttributeSet(); ~TiXmlAttributeSet();
void Add( TiXmlAttribute* attribute ); void Add( TiXmlAttribute* attribute );
void Remove( TiXmlAttribute* attribute ); void Remove( TiXmlAttribute* attribute );
TiXmlAttribute* First() const { return ( sentinel.next == &sentine l ) ? 0 : sentinel.next; } TiXmlAttribute* First() const { return ( sentinel.next == &sentine l ) ? 0 : sentinel.next; }
TiXmlAttribute* Last() const { return ( sentinel.prev == &sentine l ) ? 0 : sentinel.prev; } TiXmlAttribute* Last() const { return ( sentinel.prev == &sentine l ) ? 0 : sentinel.prev; }
TiXmlAttribute* Find( const char * name ) const;
TiXmlAttribute* Find( const std::string& name ) const; private:
private:
TiXmlAttribute sentinel; TiXmlAttribute sentinel;
}; };
/** The element is a container class. It has a value, the element name, /** The element is a container class. It has a value, the element name,
and can contain other elements, text, comments, and unknowns. and can contain other elements, text, comments, and unknowns.
Elements also contain an arbitrary number of attributes. Elements also contain an arbitrary number of attributes.
*/ */
class TiXmlElement : public TiXmlNode class TiXmlElement : public TiXmlNode
{ {
public: public:
/// Construct an element. /// Construct an element.
TiXmlElement( const std::string& value ); TiXmlElement (const char * in_value);
#ifdef TIXML_USE_STL
/// std::string constructor.
TiXmlElement( const std::string& _value ) : TiXmlNode( TiXmlNode
::ELEMENT )
{
firstChild = lastChild = 0;
value = _value . c_str ();
}
#endif
virtual ~TiXmlElement(); virtual ~TiXmlElement();
/** Given an attribute name, attribute returns the value /** Given an attribute name, attribute returns the value
for the attribute of that name, or null if none exists. for the attribute of that name, or null if none exists.
*/ */
const std::string* Attribute( const std::string& name ) const; const char * Attribute( const char * name ) const;
/** Given an attribute name, attribute returns the value /** Given an attribute name, attribute returns the value
for the attribute of that name, or null if none exists. for the attribute of that name, or null if none exists.
*/ */
const std::string* Attribute( const std::string& name, int* i ) cons t; const char * Attribute( const char * name, int & i ) const;
/** Sets an attribute of name to a given value. The attribute /** Sets an attribute of name to a given value. The attribute
will be created if it does not exist, or changed if it does. will be created if it does not exist, or changed if it does.
*/ */
void SetAttribute( const std::string& name, void SetAttribute( const char * name, const char * value );
const std::string& value );
#ifdef TIXML_USE_STL
void SetAttribute( const std::string& name, const std::string& value
) { SetAttribute (name . c_str (), value . c_str ()); }
///< STL std::string form.
void SetAttribute( const std::string& name, int value ) { SetA
ttribute (name . c_str (), value); } ///< STL std::string form.
#endif
/** Sets an attribute of name to a given value. The attribute /** Sets an attribute of name to a given value. The attribute
will be created if it does not exist, or changed if it does. will be created if it does not exist, or changed if it does.
*/ */
void SetAttribute( const std::string& name, void SetAttribute( const char * name, int value );
int value );
/** Deletes an attribute with the given name. /** Deletes an attribute with the given name.
*/ */
void RemoveAttribute( const std::string& name ); void RemoveAttribute( const char * name );
#ifdef TIXML_USE_STL
void RemoveAttribute( const std::string& name ) { RemoveAttrib
ute (name . c_str ()); } ///< STL std::string form.
#endif
TiXmlAttribute* FirstAttribute() { return attributeSet.First( TiXmlAttribute* FirstAttribute() const { return attributeSet.First(
); } ///< Access the first attribute in this element. ); } ///< Access the first attribute in this element.
TiXmlAttribute* LastAttribute() { return attributeSet.Last() TiXmlAttribute* LastAttribute() const { return attributeSet.Last()
; } ///< Access the last attribute in this element. ; } ///< Access the last attribute in this element.
// [internal use] Creates a new Element and returs it. // [internal use] Creates a new Element and returs it.
virtual TiXmlNode* Clone() const; virtual TiXmlNode* Clone() const;
// [internal use] // [internal use]
virtual void Print( FILE* fp, int depth );
protected: virtual void Print( FILE* cfile, int depth ) const;
protected:
// Used to be public [internal use]
#ifdef TIXML_USE_STL
virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
#endif
virtual void StreamOut( TIXML_OSTREAM * out ) const;
/* [internal use] /* [internal use]
Attribtue parsing starts: next char past '<' Attribtue parsing starts: next char past '<'
returns: next char past '>' returns: next char past '>'
*/ */
virtual const char* Parse( const char* ); virtual const char* Parse( const char* p );
const char* ReadValue( const char* p );
private: /* [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 );
private:
TiXmlAttributeSet attributeSet; TiXmlAttributeSet attributeSet;
}; };
/** An XML comment. /** An XML comment.
*/ */
class TiXmlComment : public TiXmlNode class TiXmlComment : public TiXmlNode
{ {
public: public:
/// Constructs an empty comment. /// Constructs an empty comment.
TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
virtual ~TiXmlComment() {} virtual ~TiXmlComment() {}
// [internal use] Creates a new Element and returs it. // [internal use] Creates a new Element and returs it.
virtual TiXmlNode* Clone() const; virtual TiXmlNode* Clone() const;
// [internal use] // [internal use]
virtual void Print( FILE* fp, int depth ); virtual void Print( FILE* cfile, int depth ) const;
protected:
protected: // used to be public
#ifdef TIXML_USE_STL
virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
#endif
virtual void StreamOut( TIXML_OSTREAM * out ) const;
/* [internal use] /* [internal use]
Attribtue parsing starts: at the ! of the !-- Attribtue parsing starts: at the ! of the !--
returns: next char past '>' returns: next char past '>'
*/ */
virtual const char* Parse( const char* ); virtual const char* Parse( const char* p );
}; };
/** XML text. Contained in an element. /** XML text. Contained in an element.
*/ */
class TiXmlText : public TiXmlNode class TiXmlText : public TiXmlNode
{ {
public: friend class TiXmlElement;
TiXmlText() : TiXmlNode( TiXmlNode::TEXT ) {} public:
/// Constructor.
TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT)
{
SetValue( initValue );
}
virtual ~TiXmlText() {} virtual ~TiXmlText() {}
#ifdef TIXML_USE_STL
/// Constructor.
TiXmlText( const std::string& initValue );
#endif
protected :
// [internal use] Creates a new Element and returns it. // [internal use] Creates a new Element and returns it.
virtual TiXmlNode* Clone() const; virtual TiXmlNode* Clone() const;
// [internal use] // [internal use]
virtual void Print( FILE* fp, int depth ); virtual void Print( FILE* cfile, int depth ) const;
virtual void StreamOut ( TIXML_OSTREAM * out ) const;
// [internal use] // [internal use]
bool Blank(); // returns true if all white space and new lines bool Blank() const; // returns true if all white space and new l
ines
/* [internal use] /* [internal use]
Attribtue parsing starts: First char of the text Attribtue parsing starts: First char of the text
returns: next char past '>' returns: next char
*/ past '>'
virtual const char* Parse( const char* ); */
virtual const char* Parse( const char* p );
// [internal use]
#ifdef TIXML_USE_STL
virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
#endif
}; };
/** In correct XML the declaration is the first entry in the file. /** In correct XML the declaration is the first entry in the file.
@verbatim @verbatim
<?xml version="1.0" standalone="yes"?> <?xml version="1.0" standalone="yes"?>
@endverbatim @endverbatim
TinyXml will happily read or write files without a declaration, TinyXml will happily read or write files without a declaration,
however. There are 3 possible attributes to the declaration: however. There are 3 possible attributes to the declaration:
version, encoding, and standalone. version, encoding, and standalone.
Note: In this version of the code, the attributes are Note: In this version of the code, the attributes are
handled as special cases, not generic attributes, simply handled as special cases, not generic attributes, simply
because there can only be at most 3 and they are always the same. because there can only be at most 3 and they are always the same.
*/ */
class TiXmlDeclaration : public TiXmlNode class TiXmlDeclaration : public TiXmlNode
{ {
public: public:
/// Construct an empty declaration. /// Construct an empty declaration.
TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {}
#ifdef TIXML_USE_STL
/// Constructor.
TiXmlDeclaration(
const std::string& _version,
const std::string& _encoding
,
const std::string& _standalo
ne )
: TiXmlNode( TiXmlNode::DECLARATION
)
{
version = _version . c_str ();
encoding = _encoding . c_str ();
standalone = _standalone . c_str ();
}
#endif
/// Construct. /// Construct.
TiXmlDeclaration( const std::string& version, TiXmlDeclaration::TiXmlDeclaration( const char * _version,
const std::string& encoding,
const std::string& standalone ); const char * _encoding,
const char * _standalone );
virtual ~TiXmlDeclaration() {} virtual ~TiXmlDeclaration() {}
/// Version. Will return empty if none was found. /// Version. Will return empty if none was found.
const std::string& Version() { return version; } const char * Version() const { return version . c_str (); }
/// Encoding. Will return empty if none was found. /// Encoding. Will return empty if none was found.
const std::string& Encoding() { return encoding; } const char * Encoding() const { return encoding . c_str () ; }
/// Is this a standalone document? /// Is this a standalone document?
const std::string& Standalone() { return standalone; } const char * Standalone() const { return standalone . c_str (); }
// [internal use] Creates a new Element and returs it. // [internal use] Creates a new Element and returs it.
virtual TiXmlNode* Clone() const; virtual TiXmlNode* Clone() const;
// [internal use] // [internal use]
virtual void Print( FILE* fp, int depth ); virtual void Print( FILE* cfile, int depth ) const;
protected: protected:
// used to be public
#ifdef TIXML_USE_STL
virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
#endif
virtual void StreamOut ( TIXML_OSTREAM * out) const;
// [internal use] // [internal use]
// Attribtue parsing starts: next char past '<' // Attribtue parsing starts: next char past '<'
// returns: next char past '>' // returns: next char past '>'
virtual const char* Parse( const char* ); virtual const char* Parse( const char* p );
private: private:
std::string version; TIXML_STRING version;
std::string encoding; TIXML_STRING encoding;
std::string standalone; TIXML_STRING standalone;
}; };
/** Any tag that tinyXml doesn't recognize is save as an /** Any tag that tinyXml doesn't recognize is save as an
unknown. It is a tag of text, but should not be modified. unknown. It is a tag of text, but should not be modified.
It will be written back to the XML, unchanged, when the file It will be written back to the XML, unchanged, when the file
is saved. is saved.
*/ */
class TiXmlUnknown : public TiXmlNode class TiXmlUnknown : public TiXmlNode
{ {
public: public:
TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
virtual ~TiXmlUnknown() {} virtual ~TiXmlUnknown() {}
// [internal use] // [internal use]
virtual TiXmlNode* Clone() const; virtual TiXmlNode* Clone() const;
// [internal use] // [internal use]
virtual void Print( FILE* fp, int depth ); virtual void Print( FILE* cfile, int depth ) const;
protected:
protected: // used to be public
#ifdef TIXML_USE_STL
virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
#endif
virtual void StreamOut ( TIXML_OSTREAM * out ) const;
/* [internal use] /* [internal use]
Attribute parsing starts: First char of the text Attribute parsing starts: First char of the text
returns: next char past '>' returns: next char past '>'
*/ */
virtual const char* Parse( const char* ); virtual const char* Parse( const char* p );
}; };
/** Always the top level node. A document binds together all the /** Always the top level node. A document binds together all the
XML pieces. It can be saved, loaded, and printed to the screen. XML pieces. It can be saved, loaded, and printed to the screen.
The 'value' of a document node is the xml file name. The 'value' of a document node is the xml file name.
*/ */
class TiXmlDocument : public TiXmlNode class TiXmlDocument : public TiXmlNode
{ {
public: public:
/// Create an empty document, that has no name. /// Create an empty document, that has no name.
TiXmlDocument(); TiXmlDocument();
/// Create a document with a name. The name of the document is also the filename of the xml. /// Create a document with a name. The name of the document is also the filename of the xml.
TiXmlDocument( const std::string& documentName ); TiXmlDocument( const char * documentName );
#ifdef TIXML_USE_STL
/// Constructor.
TiXmlDocument( const std::string& documentName ) :
TiXmlNode( TiXmlNode::DOCUMENT )
{
error = false;
}
#endif
virtual ~TiXmlDocument() {} virtual ~TiXmlDocument() {}
/** Load a file using the current document value. /** Load a file using the current document value.
Returns true if successful. Will delete any existing Returns true if successful. Will delete any existing
document data before loading. document data before loading.
*/ */
bool LoadFile(); bool LoadFile();
/// Save a file using the current document value. Returns true if su ccessful. /// Save a file using the current document value. Returns true if su ccessful.
bool SaveFile(); bool SaveFile() const;
/// Load a file using the given filename. Returns true if successful . /// Load a file using the given filename. Returns true if successful .
bool LoadFile( const std::string& filename ); bool LoadFile( const char * filename );
/// Save a file using the given filename. Returns true if successful . /// Save a file using the given filename. Returns true if successful .
bool SaveFile( const std::string& filename ); bool SaveFile( const char * filename ) const;
#ifdef TIXML_USE_STL
bool LoadFile( const std::string& filename ); ///<
STL std::string version.
bool SaveFile( const std::string& filename ) const; ///<
STL std::string version.
#endif
/// Parse the given null terminated block of xml data. /// Parse the given null terminated block of xml data.
const char* Parse( const char* ); virtual const char* Parse( const char* p );
/** Get the root element -- the only top level element -- of the doc
ument.
In well formed XML, there should only be one. TinyXml is tol
erant of
multiple elements at the document level.
*/
TiXmlElement* RootElement() const { return FirstChildE
lement(); }
/// If, during parsing, a error occurs, Error will be set to true. /// If, during parsing, a error occurs, Error will be set to true.
bool Error() { return err bool Error() const { re
or; } turn error; }
/// Contains a textual (english) description of the error if one occ urs. /// Contains a textual (english) description of the error if one occ urs.
const std::string& ErrorDesc() { return errorDesc; } const char * ErrorDesc() const { return errorDesc . c_str (); }
/// Write the document to a file -- usually invoked by SaveFile. /** Generally, you probably want the error string ( ErrorDesc() ). B
virtual void Print( FILE* fp, int depth = 0 ); ut if you
/// Dump the document to standard out. prefer the ErrorId, this function will fetch it.
void Print() */
{ Print( stdout, 0 ); } const int ErrorId() const { return err
orId; }
/// If you have handled the error, it can be reset with this call.
void ClearError() { er
ror = false; errorId = 0; errorDesc = ""; }
/** Dump the document to standard out. */
void Print() const
{ Print( stdout, 0 ); }
// [internal use] // [internal use]
virtual TiXmlNode* Clone() const; virtual void Print( FILE* cfile, int depth = 0 ) const;
// [internal use] // [internal use]
void SetError( int err ) { assert( err > 0 && err < TIX ML_ERROR_STRING_COUNT ); void SetError( int err ) { assert( err > 0 && err < TIX ML_ERROR_STRING_COUNT );
erro error = true;
r = true; errorId = err;
erro errorDesc = errorString[ errorId ]; }
rId = err;
erro
rDesc = errorString[ errorId ]; }
private: protected :
virtual void StreamOut ( TIXML_OSTREAM * out) const;
// [internal use]
virtual TiXmlNode* Clone() const;
#ifdef TIXML_USE_STL
virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
#endif
private:
bool error; bool error;
int errorId; int errorId;
std::string errorDesc; TIXML_STRING errorDesc;
}; };
#endif #endif
 End of changes. 96 change blocks. 
157 lines changed or deleted 527 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/