mirror of https://github.com/AxioDL/tinyxml2.git
print to memory support
This commit is contained in:
parent
09a11c5964
commit
ae25a44d94
101
tinyxml2.cpp
101
tinyxml2.cpp
|
@ -5,6 +5,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <new.h>
|
#include <new.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
//#pragma warning ( disable : 4291 )
|
//#pragma warning ( disable : 4291 )
|
||||||
|
|
||||||
|
@ -332,6 +333,13 @@ void XMLNode::Unlink( XMLNode* child )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLNode::DeleteChild( XMLNode* node )
|
||||||
|
{
|
||||||
|
TIXMLASSERT( node->parent == this );
|
||||||
|
DELETE_NODE( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
|
XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
|
||||||
{
|
{
|
||||||
if ( lastChild ) {
|
if ( lastChild ) {
|
||||||
|
@ -428,13 +436,6 @@ const XMLElement* XMLNode::LastChildElement( const char* value ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLNode::DeleteChild( XMLNode* node )
|
|
||||||
{
|
|
||||||
TIXMLASSERT( node->parent == this );
|
|
||||||
TIXMLASSERT( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char* XMLNode::ParseDeep( char* p )
|
char* XMLNode::ParseDeep( char* p )
|
||||||
{
|
{
|
||||||
while( p && *p ) {
|
while( p && *p ) {
|
||||||
|
@ -733,6 +734,25 @@ void XMLElement::LinkAttribute( XMLAttribute* attrib )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLElement::DeleteAttribute( const char* name )
|
||||||
|
{
|
||||||
|
XMLAttribute* prev = 0;
|
||||||
|
for( XMLAttribute* a=rootAttribute; a; a=a->next ) {
|
||||||
|
if ( XMLUtil::StringEqual( name, a->Name() ) ) {
|
||||||
|
if ( prev ) {
|
||||||
|
prev->next = a->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rootAttribute = a->next;
|
||||||
|
}
|
||||||
|
DELETE_ATTRIBUTE( a );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char* XMLElement::ParseAttributes( char* p, bool* closedElement )
|
char* XMLElement::ParseAttributes( char* p, bool* closedElement )
|
||||||
{
|
{
|
||||||
const char* start = p;
|
const char* start = p;
|
||||||
|
@ -947,13 +967,45 @@ XMLStreamer::XMLStreamer( FILE* file ) : fp( file ), depth( 0 ), elementJustOpen
|
||||||
entityFlag[ entities[i].value ] = true;
|
entityFlag[ entities[i].value ] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
buffer.Push( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLStreamer::Print( const char* format, ... )
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
va_start( va, format );
|
||||||
|
|
||||||
|
if ( fp ) {
|
||||||
|
vfprintf( fp, format, va );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// This seems brutally complex. Haven't figured out a better
|
||||||
|
// way on windows.
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
int len = -1;
|
||||||
|
while ( len < 0 ) {
|
||||||
|
len = vsnprintf_s( accumulator.Mem(), accumulator.Capacity(), accumulator.Capacity()-1, format, va );
|
||||||
|
if ( len < 0 ) {
|
||||||
|
accumulator.PushArr( 1000 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char* p = buffer.PushArr( len ) - 1;
|
||||||
|
memcpy( p, accumulator.Mem(), len+1 );
|
||||||
|
#else
|
||||||
|
int len = vsnprintf( 0, 0, format, va );
|
||||||
|
char* p = buffer.PushArr( len ) - 1;
|
||||||
|
vsprintf_s( p, len+1, format, va );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
va_end( va );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLStreamer::PrintSpace( int depth )
|
void XMLStreamer::PrintSpace( int depth )
|
||||||
{
|
{
|
||||||
for( int i=0; i<depth; ++i ) {
|
for( int i=0; i<depth; ++i ) {
|
||||||
fprintf( fp, " " );
|
Print( " " );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -970,12 +1022,12 @@ void XMLStreamer::PrintString( const char* p )
|
||||||
// entity, and keep looking.
|
// entity, and keep looking.
|
||||||
if ( entityFlag[*q] ) {
|
if ( entityFlag[*q] ) {
|
||||||
while ( p < q ) {
|
while ( p < q ) {
|
||||||
fputc( *p, fp );
|
Print( "%c", *p );
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
for( int i=0; i<NUM_ENTITIES; ++i ) {
|
for( int i=0; i<NUM_ENTITIES; ++i ) {
|
||||||
if ( entities[i].value == *q ) {
|
if ( entities[i].value == *q ) {
|
||||||
fprintf( fp, "&%s;", entities[i].pattern );
|
Print( "&%s;", entities[i].pattern );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -987,10 +1039,11 @@ void XMLStreamer::PrintString( const char* p )
|
||||||
// Flush the remaining string. This will be the entire
|
// Flush the remaining string. This will be the entire
|
||||||
// string if an entity wasn't found.
|
// string if an entity wasn't found.
|
||||||
if ( q-p > 0 ) {
|
if ( q-p > 0 ) {
|
||||||
fprintf( fp, "%s", p );
|
Print( "%s", p );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLStreamer::OpenElement( const char* name )
|
void XMLStreamer::OpenElement( const char* name )
|
||||||
{
|
{
|
||||||
if ( elementJustOpened ) {
|
if ( elementJustOpened ) {
|
||||||
|
@ -999,11 +1052,11 @@ void XMLStreamer::OpenElement( const char* name )
|
||||||
stack.Push( name );
|
stack.Push( name );
|
||||||
|
|
||||||
if ( textDepth < 0 && depth > 0) {
|
if ( textDepth < 0 && depth > 0) {
|
||||||
fprintf( fp, "\n" );
|
Print( "\n" );
|
||||||
PrintSpace( depth );
|
PrintSpace( depth );
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf( fp, "<%s", name );
|
Print( "<%s", name );
|
||||||
elementJustOpened = true;
|
elementJustOpened = true;
|
||||||
++depth;
|
++depth;
|
||||||
}
|
}
|
||||||
|
@ -1012,9 +1065,9 @@ void XMLStreamer::OpenElement( const char* name )
|
||||||
void XMLStreamer::PushAttribute( const char* name, const char* value )
|
void XMLStreamer::PushAttribute( const char* name, const char* value )
|
||||||
{
|
{
|
||||||
TIXMLASSERT( elementJustOpened );
|
TIXMLASSERT( elementJustOpened );
|
||||||
fprintf( fp, " %s=\"", name );
|
Print( " %s=\"", name );
|
||||||
PrintString( value );
|
PrintString( value );
|
||||||
fprintf( fp, "\"" );
|
Print( "\"" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1024,20 +1077,20 @@ void XMLStreamer::CloseElement()
|
||||||
const char* name = stack.Pop();
|
const char* name = stack.Pop();
|
||||||
|
|
||||||
if ( elementJustOpened ) {
|
if ( elementJustOpened ) {
|
||||||
fprintf( fp, "/>" );
|
Print( "/>" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( textDepth < 0 ) {
|
if ( textDepth < 0 ) {
|
||||||
fprintf( fp, "\n" );
|
Print( "\n" );
|
||||||
PrintSpace( depth );
|
PrintSpace( depth );
|
||||||
}
|
}
|
||||||
fprintf( fp, "</%s>", name );
|
Print( "</%s>", name );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( textDepth == depth )
|
if ( textDepth == depth )
|
||||||
textDepth = -1;
|
textDepth = -1;
|
||||||
if ( depth == 0 )
|
if ( depth == 0 )
|
||||||
fprintf( fp, "\n" );
|
Print( "\n" );
|
||||||
elementJustOpened = false;
|
elementJustOpened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1045,7 +1098,7 @@ void XMLStreamer::CloseElement()
|
||||||
void XMLStreamer::SealElement()
|
void XMLStreamer::SealElement()
|
||||||
{
|
{
|
||||||
elementJustOpened = false;
|
elementJustOpened = false;
|
||||||
fprintf( fp, ">" );
|
Print( ">" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1057,10 +1110,10 @@ void XMLStreamer::PushText( const char* text, bool cdata )
|
||||||
SealElement();
|
SealElement();
|
||||||
}
|
}
|
||||||
if ( cdata )
|
if ( cdata )
|
||||||
fprintf( fp, "<![CDATA[" );
|
Print( "<![CDATA[" );
|
||||||
PrintString( text );
|
PrintString( text );
|
||||||
if ( cdata )
|
if ( cdata )
|
||||||
fprintf( fp, "]]>" );
|
Print( "]]>" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1070,10 +1123,10 @@ void XMLStreamer::PushComment( const char* comment )
|
||||||
SealElement();
|
SealElement();
|
||||||
}
|
}
|
||||||
if ( textDepth < 0 && depth > 0) {
|
if ( textDepth < 0 && depth > 0) {
|
||||||
fprintf( fp, "\n" );
|
Print( "\n" );
|
||||||
PrintSpace( depth );
|
PrintSpace( depth );
|
||||||
}
|
}
|
||||||
fprintf( fp, "<!--%s-->", comment );
|
Print( "<!--%s-->", comment );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
82
tinyxml2.h
82
tinyxml2.h
|
@ -13,13 +13,16 @@
|
||||||
X hide copy constructor
|
X hide copy constructor
|
||||||
X hide = operator
|
X hide = operator
|
||||||
X UTF8 support: isAlpha, etc.
|
X UTF8 support: isAlpha, etc.
|
||||||
- string buffer for sets. (Grr.)
|
X string buffer for sets. (Grr.)
|
||||||
- MS BOM
|
- MS BOM
|
||||||
- print to memory buffer
|
- print to memory buffer
|
||||||
- tests from xml1
|
- tests from xml1
|
||||||
- xml1 tests especially UTF-8
|
- xml1 tests especially UTF-8
|
||||||
- perf test: xml1
|
- perf test: xml1
|
||||||
- perf test: xenowar
|
- perf test: xenowar
|
||||||
|
- test: load(char*)
|
||||||
|
- test: load(FILE*)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
@ -64,7 +67,7 @@
|
||||||
#define TIXML_SNPRINTF _snprintf
|
#define TIXML_SNPRINTF _snprintf
|
||||||
#define TIXML_SSCANF sscanf
|
#define TIXML_SSCANF sscanf
|
||||||
#elif defined(__GNUC__) && (__GNUC__ >= 3 )
|
#elif defined(__GNUC__) && (__GNUC__ >= 3 )
|
||||||
// GCC version 3 and higher.s
|
// GCC version 3 and higher
|
||||||
//#warning( "Using sn* functions." )
|
//#warning( "Using sn* functions." )
|
||||||
#define TIXML_SNPRINTF snprintf
|
#define TIXML_SNPRINTF snprintf
|
||||||
#define TIXML_SSCANF sscanf
|
#define TIXML_SSCANF sscanf
|
||||||
|
@ -87,6 +90,12 @@ class XMLUnknown;
|
||||||
|
|
||||||
class XMLStreamer;
|
class XMLStreamer;
|
||||||
|
|
||||||
|
/*
|
||||||
|
A class that wraps strings. Normally stores the start and end
|
||||||
|
pointers into the XML file itself, and will apply normalization
|
||||||
|
and entity transalion if actually read. Can also store (and memory
|
||||||
|
manage) a traditional char[]
|
||||||
|
*/
|
||||||
class StrPair
|
class StrPair
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -132,6 +141,11 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
A dynamic array of Plain Old Data. Doesn't support constructors, etc.
|
||||||
|
Has a small initial memory pool, so that low or no usage will not
|
||||||
|
cause a call to new/delete
|
||||||
|
*/
|
||||||
template <class T, int INIT>
|
template <class T, int INIT>
|
||||||
class DynArray
|
class DynArray
|
||||||
{
|
{
|
||||||
|
@ -170,12 +184,13 @@ public:
|
||||||
size -= count;
|
size -= count;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Empty() const { return size == 0; }
|
bool Empty() const { return size == 0; }
|
||||||
T& operator[](int i) { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }
|
T& operator[](int i) { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }
|
||||||
const T& operator[](int i) const { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }
|
const T& operator[](int i) const { TIXMLASSERT( i>= 0 && i < size ); return mem[i]; }
|
||||||
int Size() const { return size; }
|
int Size() const { return size; }
|
||||||
const T* Mem() const { return mem; }
|
int Capacity() const { return allocated; }
|
||||||
T* Mem() { return mem; }
|
const T* Mem() const { return mem; }
|
||||||
|
T* Mem() { return mem; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -197,6 +212,10 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parent virtual class a a pool for fast allocation
|
||||||
|
and deallocation of objects.
|
||||||
|
*/
|
||||||
class MemPool
|
class MemPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -209,6 +228,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Template child class to create pools of the correct type.
|
||||||
|
*/
|
||||||
template< int SIZE >
|
template< int SIZE >
|
||||||
class MemPoolT : public MemPool
|
class MemPoolT : public MemPool
|
||||||
{
|
{
|
||||||
|
@ -321,13 +343,16 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Utility functionality.
|
||||||
|
*/
|
||||||
class XMLUtil
|
class XMLUtil
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
|
// Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
|
||||||
// correct, but simple, and usually works.
|
// correct, but simple, and usually works.
|
||||||
static const char* SkipWhiteSpace( const char* p ) { while( IsUTF8Continuation(*p) || isspace( *p ) ) { ++p; } return p; }
|
static const char* SkipWhiteSpace( const char* p ) { while( !IsUTF8Continuation(*p) && isspace( *p ) ) { ++p; } return p; }
|
||||||
static char* SkipWhiteSpace( char* p ) { while( IsUTF8Continuation(*p) || isspace( *p ) ) { ++p; } return p; }
|
static char* SkipWhiteSpace( char* p ) { while( !IsUTF8Continuation(*p) && isspace( *p ) ) { ++p; } return p; }
|
||||||
|
|
||||||
inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
|
inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
@ -418,11 +443,17 @@ public:
|
||||||
*/
|
*/
|
||||||
XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
|
XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tests: All (used by destructor)
|
||||||
|
*/
|
||||||
void ClearChildren();
|
void ClearChildren();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tests: Progammatic DOM
|
||||||
|
*/
|
||||||
void DeleteChild( XMLNode* node );
|
void DeleteChild( XMLNode* node );
|
||||||
|
|
||||||
virtual bool Accept( XMLVisitor* visitor ) const = 0;
|
virtual bool Accept( XMLVisitor* visitor ) const = 0;
|
||||||
//virtual void Print( XMLStreamer* streamer );
|
|
||||||
|
|
||||||
virtual char* ParseDeep( char* );
|
virtual char* ParseDeep( char* );
|
||||||
virtual bool IsClosingElement() const { return false; }
|
virtual bool IsClosingElement() const { return false; }
|
||||||
|
@ -549,6 +580,12 @@ public:
|
||||||
const char* Value() const { return value.GetStr(); }
|
const char* Value() const { return value.GetStr(); }
|
||||||
const XMLAttribute* Next() const { return next; }
|
const XMLAttribute* Next() const { return next; }
|
||||||
|
|
||||||
|
int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( &i ); return i; }
|
||||||
|
unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( &i ); return i; }
|
||||||
|
bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( &b ); return b; }
|
||||||
|
double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( &d ); return d; }
|
||||||
|
float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( &f ); return f; }
|
||||||
|
|
||||||
int QueryIntAttribute( int* value ) const;
|
int QueryIntAttribute( int* value ) const;
|
||||||
int QueryUnsignedAttribute( unsigned int* value ) const;
|
int QueryUnsignedAttribute( unsigned int* value ) const;
|
||||||
int QueryBoolAttribute( bool* value ) const;
|
int QueryBoolAttribute( bool* value ) const;
|
||||||
|
@ -612,7 +649,10 @@ public:
|
||||||
void SetAttribute( const char* name, bool value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
|
void SetAttribute( const char* name, bool value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
|
||||||
void SetAttribute( const char* name, double value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
|
void SetAttribute( const char* name, double value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
|
||||||
|
|
||||||
void RemoveAttribute( const char* name );
|
/**
|
||||||
|
Tests: Programmatic DOM
|
||||||
|
*/
|
||||||
|
void DeleteAttribute( const char* name );
|
||||||
|
|
||||||
const XMLAttribute* FirstAttribute() const { return rootAttribute; }
|
const XMLAttribute* FirstAttribute() const { return rootAttribute; }
|
||||||
const XMLAttribute* FindAttribute( const char* name ) const;
|
const XMLAttribute* FindAttribute( const char* name ) const;
|
||||||
|
@ -657,18 +697,23 @@ public:
|
||||||
virtual bool Accept( XMLVisitor* visitor ) const;
|
virtual bool Accept( XMLVisitor* visitor ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Testing: Programmatic DOM
|
Tests: Programmatic DOM
|
||||||
*/
|
*/
|
||||||
XMLElement* NewElement( const char* name );
|
XMLElement* NewElement( const char* name );
|
||||||
/**
|
/**
|
||||||
Testing: Programmatic DOM
|
Tests: Programmatic DOM
|
||||||
*/
|
*/
|
||||||
XMLComment* NewComment( const char* comment );
|
XMLComment* NewComment( const char* comment );
|
||||||
/**
|
/**
|
||||||
Testing: Programmatic DOM
|
Tests: Programmatic DOM
|
||||||
*/
|
*/
|
||||||
XMLText* NewText( const char* text );
|
XMLText* NewText( const char* text );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Tests: Programmatic DOM
|
||||||
|
*/
|
||||||
|
void DeleteNode( XMLNode* node ) { node->parent->DeleteChild( node ); }
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NO_ERROR = 0,
|
NO_ERROR = 0,
|
||||||
ERROR_ELEMENT_MISMATCH,
|
ERROR_ELEMENT_MISMATCH,
|
||||||
|
@ -705,7 +750,7 @@ private:
|
||||||
class XMLStreamer : public XMLVisitor
|
class XMLStreamer : public XMLVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XMLStreamer( FILE* file );
|
XMLStreamer( FILE* file=0 );
|
||||||
~XMLStreamer() {}
|
~XMLStreamer() {}
|
||||||
|
|
||||||
void OpenElement( const char* name );
|
void OpenElement( const char* name );
|
||||||
|
@ -724,11 +769,13 @@ public:
|
||||||
virtual bool Visit( const XMLText& text );
|
virtual bool Visit( const XMLText& text );
|
||||||
virtual bool Visit( const XMLComment& comment );
|
virtual bool Visit( const XMLComment& comment );
|
||||||
|
|
||||||
|
const char* CStr() const { return buffer.Mem(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SealElement();
|
void SealElement();
|
||||||
void PrintSpace( int depth );
|
void PrintSpace( int depth );
|
||||||
void PrintString( const char* ); // prints out, after detecting entities.
|
void PrintString( const char* ); // prints out, after detecting entities.
|
||||||
|
void Print( const char* format, ... );
|
||||||
|
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
int depth;
|
int depth;
|
||||||
|
@ -741,6 +788,7 @@ private:
|
||||||
bool entityFlag[ENTITY_RANGE];
|
bool entityFlag[ENTITY_RANGE];
|
||||||
|
|
||||||
DynArray< const char*, 10 > stack;
|
DynArray< const char*, 10 > stack;
|
||||||
|
DynArray< char, 20 > buffer, accumulator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -748,4 +796,4 @@ private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // TINYXML2_INCLUDED
|
#endif // TINYXML2_INCLUDED
|
||||||
|
|
20
xmltest.cpp
20
xmltest.cpp
|
@ -147,6 +147,26 @@ int main( int argc, const char* argv )
|
||||||
XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
|
XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
|
||||||
XMLTest( "Programmatic DOM", "& Text!",
|
XMLTest( "Programmatic DOM", "& Text!",
|
||||||
doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
|
doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
|
||||||
|
|
||||||
|
// And now deletion:
|
||||||
|
element->DeleteChild( sub[2] );
|
||||||
|
doc->DeleteNode( comment );
|
||||||
|
|
||||||
|
element->FirstChildElement()->SetAttribute( "attrib", true );
|
||||||
|
element->LastChildElement()->DeleteAttribute( "attrib" );
|
||||||
|
|
||||||
|
XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) );
|
||||||
|
int value = 10;
|
||||||
|
int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value );
|
||||||
|
XMLTest( "Programmatic DOM", result, NO_ATTRIBUTE );
|
||||||
|
XMLTest( "Programmatic DOM", value, 10 );
|
||||||
|
|
||||||
|
doc->Print();
|
||||||
|
|
||||||
|
XMLStreamer streamer;
|
||||||
|
doc->Print( &streamer );
|
||||||
|
printf( "%s", streamer.CStr() );
|
||||||
|
|
||||||
delete doc;
|
delete doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue