mirror of https://github.com/AxioDL/tinyxml2.git
Merge branch 'master' of github.com:leethomason/tinyxml2
This commit is contained in:
commit
975426752c
|
@ -0,0 +1,48 @@
|
||||||
|
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
|
||||||
|
cmake_policy(VERSION 2.6)
|
||||||
|
|
||||||
|
project(tinyxml2)
|
||||||
|
#enable_testing()
|
||||||
|
|
||||||
|
#CMAKE_BUILD_TOOL
|
||||||
|
|
||||||
|
################################
|
||||||
|
# Add common source
|
||||||
|
|
||||||
|
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/.")
|
||||||
|
|
||||||
|
################################
|
||||||
|
# Add custom target to copy all data
|
||||||
|
|
||||||
|
set(TARGET_DATA_COPY DATA_COPY)
|
||||||
|
if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
add_custom_target(
|
||||||
|
${TARGET_DATA_COPY}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "In source build")
|
||||||
|
else(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
add_custom_target(
|
||||||
|
${TARGET_DATA_COPY}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/dream.xml ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/utf8test.xml ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/utf8testverify.xml ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
endif(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
set(OGL_DATA_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data)
|
||||||
|
|
||||||
|
################################
|
||||||
|
# Add definitions
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif(MSVC)
|
||||||
|
|
||||||
|
################################
|
||||||
|
# Add targets
|
||||||
|
|
||||||
|
add_library(tinyxml2 STATIC tinyxml2.cpp tinyxml2.h)
|
||||||
|
|
||||||
|
add_executable(test xmltest.cpp)
|
||||||
|
add_dependencies(test tinyxml2)
|
||||||
|
add_dependencies(test ${TARGET_DATA_COPY})
|
||||||
|
target_link_libraries(test tinyxml2)
|
||||||
|
#add_test(test ${SAMPLE_NAME} COMMAND $<TARGET_FILE:${SAMPLE_NAME}>)
|
4
dox
4
dox
|
@ -32,7 +32,7 @@ PROJECT_NAME = "TinyXML-2"
|
||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.9.3
|
PROJECT_NUMBER = 0.9.4
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer
|
# for a project that appears at the top of each page and should give viewer
|
||||||
|
@ -661,7 +661,7 @@ WARN_LOGFILE =
|
||||||
# directories like "/usr/src/myproject". Separate the files or directories
|
# directories like "/usr/src/myproject". Separate the files or directories
|
||||||
# with spaces.
|
# with spaces.
|
||||||
|
|
||||||
INPUT = tinyxml2.h readme.txt
|
INPUT = tinyxml2.h xmltest.h readme.txt
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||||
|
|
|
@ -11,8 +11,7 @@ github.com/leethomason/tinyxml2
|
||||||
The online HTML version of these docs:
|
The online HTML version of these docs:
|
||||||
http://grinninglizard.com/tinyxml2docs/index.html
|
http://grinninglizard.com/tinyxml2docs/index.html
|
||||||
|
|
||||||
Where examples are in the "related pages" tab:
|
Examples are in the "related pages" tab of the HTML docs.
|
||||||
http://grinninglizard.com/tinyxml2docs/pages.html
|
|
||||||
|
|
||||||
<h2> What it does. </h2>
|
<h2> What it does. </h2>
|
||||||
|
|
||||||
|
@ -243,8 +242,9 @@ And additionally a test file:
|
||||||
<li>xmltest.cpp</li>
|
<li>xmltest.cpp</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
Simply compile and run. There is a visual studio 2010 project included.
|
Simply compile and run. There is a visual studio 2010 project included, a simple Makefile,
|
||||||
|
an XCode project, and a cmake CMakeLists.txt included to help you. The top of tinyxml.h
|
||||||
|
even has a simple g++ command line if you are are *nix and don't want to use a build system.
|
||||||
|
|
||||||
<h2> Documentation </h2>
|
<h2> Documentation </h2>
|
||||||
|
|
||||||
|
|
46
tinyxml2.cpp
46
tinyxml2.cpp
|
@ -24,7 +24,6 @@ distribution.
|
||||||
#include "tinyxml2.h"
|
#include "tinyxml2.h"
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
#include <cstdarg>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
@ -998,7 +997,7 @@ void XMLAttribute::SetAttribute( const char* v )
|
||||||
void XMLAttribute::SetAttribute( int v )
|
void XMLAttribute::SetAttribute( int v )
|
||||||
{
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v );
|
TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v );
|
||||||
value.SetStr( buf );
|
value.SetStr( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1006,7 +1005,7 @@ void XMLAttribute::SetAttribute( int v )
|
||||||
void XMLAttribute::SetAttribute( unsigned v )
|
void XMLAttribute::SetAttribute( unsigned v )
|
||||||
{
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%u", v );
|
TIXML_SNPRINTF( buf, BUF_SIZE, "%u", v );
|
||||||
value.SetStr( buf );
|
value.SetStr( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,21 +1013,21 @@ void XMLAttribute::SetAttribute( unsigned v )
|
||||||
void XMLAttribute::SetAttribute( bool v )
|
void XMLAttribute::SetAttribute( bool v )
|
||||||
{
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v ? 1 : 0 );
|
TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v ? 1 : 0 );
|
||||||
value.SetStr( buf );
|
value.SetStr( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLAttribute::SetAttribute( double v )
|
void XMLAttribute::SetAttribute( double v )
|
||||||
{
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v );
|
TIXML_SNPRINTF( buf, BUF_SIZE, "%f", v );
|
||||||
value.SetStr( buf );
|
value.SetStr( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLAttribute::SetAttribute( float v )
|
void XMLAttribute::SetAttribute( float v )
|
||||||
{
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v );
|
TIXML_SNPRINTF( buf, BUF_SIZE, "%f", v );
|
||||||
value.SetStr( buf );
|
value.SetStr( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1408,7 +1407,7 @@ int XMLDocument::LoadFile( FILE* fp )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLDocument::SaveFile( const char* filename )
|
int XMLDocument::SaveFile( const char* filename )
|
||||||
{
|
{
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning ( push )
|
#pragma warning ( push )
|
||||||
|
@ -1418,14 +1417,21 @@ void XMLDocument::SaveFile( const char* filename )
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning ( pop )
|
#pragma warning ( pop )
|
||||||
#endif
|
#endif
|
||||||
if ( fp ) {
|
if ( !fp ) {
|
||||||
|
SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 );
|
||||||
|
return errorID;
|
||||||
|
}
|
||||||
|
SaveFile(fp);
|
||||||
|
fclose( fp );
|
||||||
|
return errorID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int XMLDocument::SaveFile( FILE* fp )
|
||||||
|
{
|
||||||
XMLPrinter stream( fp );
|
XMLPrinter stream( fp );
|
||||||
Print( &stream );
|
Print( &stream );
|
||||||
fclose( fp );
|
return errorID;
|
||||||
}
|
|
||||||
else {
|
|
||||||
SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1481,11 +1487,9 @@ void XMLDocument::PrintError() const
|
||||||
|
|
||||||
if ( errorStr1 ) {
|
if ( errorStr1 ) {
|
||||||
TIXML_SNPRINTF( buf1, LEN, "%s", errorStr1 );
|
TIXML_SNPRINTF( buf1, LEN, "%s", errorStr1 );
|
||||||
buf1[LEN-1] = 0;
|
|
||||||
}
|
}
|
||||||
if ( errorStr2 ) {
|
if ( errorStr2 ) {
|
||||||
TIXML_SNPRINTF( buf2, LEN, "%s", errorStr2 );
|
TIXML_SNPRINTF( buf2, LEN, "%s", errorStr2 );
|
||||||
buf2[LEN-1] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf( "XMLDocument error id=%d str1=%s str2=%s\n",
|
printf( "XMLDocument error id=%d str1=%s str2=%s\n",
|
||||||
|
@ -1534,10 +1538,10 @@ void XMLPrinter::Print( const char* format, ... )
|
||||||
int len = -1;
|
int len = -1;
|
||||||
int expand = 1000;
|
int expand = 1000;
|
||||||
while ( len < 0 ) {
|
while ( len < 0 ) {
|
||||||
len = vsnprintf_s( accumulator.Mem(), accumulator.Capacity(), accumulator.Capacity()-1, format, va );
|
len = vsnprintf_s( accumulator.Mem(), accumulator.Capacity(), _TRUNCATE, format, va );
|
||||||
if ( len < 0 ) {
|
if ( len < 0 ) {
|
||||||
accumulator.PushArr( expand );
|
|
||||||
expand *= 3/2;
|
expand *= 3/2;
|
||||||
|
accumulator.PushArr( expand );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char* p = buffer.PushArr( len ) - 1;
|
char* p = buffer.PushArr( len ) - 1;
|
||||||
|
@ -1644,7 +1648,7 @@ void XMLPrinter::PushAttribute( const char* name, const char* value )
|
||||||
void XMLPrinter::PushAttribute( const char* name, int v )
|
void XMLPrinter::PushAttribute( const char* name, int v )
|
||||||
{
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v );
|
TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v );
|
||||||
PushAttribute( name, buf );
|
PushAttribute( name, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1652,7 +1656,7 @@ void XMLPrinter::PushAttribute( const char* name, int v )
|
||||||
void XMLPrinter::PushAttribute( const char* name, unsigned v )
|
void XMLPrinter::PushAttribute( const char* name, unsigned v )
|
||||||
{
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%u", v );
|
TIXML_SNPRINTF( buf, BUF_SIZE, "%u", v );
|
||||||
PushAttribute( name, buf );
|
PushAttribute( name, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1660,7 +1664,7 @@ void XMLPrinter::PushAttribute( const char* name, unsigned v )
|
||||||
void XMLPrinter::PushAttribute( const char* name, bool v )
|
void XMLPrinter::PushAttribute( const char* name, bool v )
|
||||||
{
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v ? 1 : 0 );
|
TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v ? 1 : 0 );
|
||||||
PushAttribute( name, buf );
|
PushAttribute( name, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1668,7 +1672,7 @@ void XMLPrinter::PushAttribute( const char* name, bool v )
|
||||||
void XMLPrinter::PushAttribute( const char* name, double v )
|
void XMLPrinter::PushAttribute( const char* name, double v )
|
||||||
{
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v );
|
TIXML_SNPRINTF( buf, BUF_SIZE, "%f", v );
|
||||||
PushAttribute( name, buf );
|
PushAttribute( name, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
274
tinyxml2.h
274
tinyxml2.h
|
@ -29,6 +29,7 @@ distribution.
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cstdarg>
|
||||||
#else
|
#else
|
||||||
// Not completely sure all the interesting systems
|
// Not completely sure all the interesting systems
|
||||||
// can handle the new headers; can switch this if
|
// can handle the new headers; can switch this if
|
||||||
|
@ -70,33 +71,33 @@ distribution.
|
||||||
#endif
|
#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
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
|
||||||
// Microsoft visual studio, version 2005 and higher.
|
// Microsoft visual studio, version 2005 and higher.
|
||||||
#define TIXML_SNPRINTF _snprintf_s
|
/*int _snprintf_s(
|
||||||
|
char *buffer,
|
||||||
|
size_t sizeOfBuffer,
|
||||||
|
size_t count,
|
||||||
|
const char *format [,
|
||||||
|
argument] ...
|
||||||
|
);*/
|
||||||
|
inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) {
|
||||||
|
va_list va;
|
||||||
|
va_start( va, format );
|
||||||
|
int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
|
||||||
|
va_end( va );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
#define TIXML_SSCANF sscanf_s
|
#define TIXML_SSCANF sscanf_s
|
||||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
|
#else
|
||||||
// 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
|
// 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
|
||||||
#else
|
|
||||||
#define TIXML_SNPRINTF snprintf
|
|
||||||
#define TIXML_SSCANF sscanf
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const int TIXML2_MAJOR_VERSION = 0;
|
static const int TIXML2_MAJOR_VERSION = 0;
|
||||||
static const int TIXML2_MINOR_VERSION = 9;
|
static const int TIXML2_MINOR_VERSION = 9;
|
||||||
static const int TIXML2_PATCH_VERSION = 3;
|
static const int TIXML2_PATCH_VERSION = 4;
|
||||||
|
|
||||||
namespace tinyxml2
|
namespace tinyxml2
|
||||||
{
|
{
|
||||||
|
@ -1007,12 +1008,14 @@ public:
|
||||||
an errorID.
|
an errorID.
|
||||||
*/
|
*/
|
||||||
int Parse( const char* xml );
|
int Parse( const char* xml );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Load an XML file from disk.
|
Load an XML file from disk.
|
||||||
Returns XML_NO_ERROR (0) on success, or
|
Returns XML_NO_ERROR (0) on success, or
|
||||||
an errorID.
|
an errorID.
|
||||||
*/
|
*/
|
||||||
int LoadFile( const char* filename );
|
int LoadFile( const char* filename );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Load an XML file from disk. You are responsible
|
Load an XML file from disk. You are responsible
|
||||||
for providing and closing the FILE*.
|
for providing and closing the FILE*.
|
||||||
|
@ -1021,10 +1024,22 @@ public:
|
||||||
an errorID.
|
an errorID.
|
||||||
*/
|
*/
|
||||||
int LoadFile( FILE* );
|
int LoadFile( FILE* );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Save the XML file to disk.
|
Save the XML file to disk.
|
||||||
|
Returns XML_NO_ERROR (0) on success, or
|
||||||
|
an errorID.
|
||||||
*/
|
*/
|
||||||
void SaveFile( const char* filename );
|
int SaveFile( const char* filename );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Save the XML file to disk. You are responsible
|
||||||
|
for providing and closing the FILE*.
|
||||||
|
|
||||||
|
Returns XML_NO_ERROR (0) on success, or
|
||||||
|
an errorID.
|
||||||
|
*/
|
||||||
|
int SaveFile( FILE* );
|
||||||
|
|
||||||
bool ProcessEntities() const { return processEntities; }
|
bool ProcessEntities() const { return processEntities; }
|
||||||
|
|
||||||
|
@ -1131,6 +1146,139 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A XMLHandle is a class that wraps a node pointer with null checks; this is
|
||||||
|
an incredibly useful thing. Note that XMLHandle 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
|
||||||
|
XMLElement* root = document.FirstChildElement( "Document" );
|
||||||
|
if ( root )
|
||||||
|
{
|
||||||
|
XMLElement* element = root->FirstChildElement( "Element" );
|
||||||
|
if ( element )
|
||||||
|
{
|
||||||
|
XMLElement* child = element->FirstChildElement( "Child" );
|
||||||
|
if ( child )
|
||||||
|
{
|
||||||
|
XMLElement* child2 = child->NextSiblingElement( "Child" );
|
||||||
|
if ( child2 )
|
||||||
|
{
|
||||||
|
// Finally do something useful.
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
|
||||||
|
of such code. A XMLHandle checks for null pointers so it is perfectly safe
|
||||||
|
and correct to use:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
XMLHandle docHandle( &document );
|
||||||
|
XMLElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild().NextSibling().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
|
||||||
|
XMLHandle handleCopy = handle;
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
|
||||||
|
*/
|
||||||
|
class XMLHandle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
|
||||||
|
XMLHandle( XMLNode* _node ) { node = _node; }
|
||||||
|
/// Create a handle from a node.
|
||||||
|
XMLHandle( XMLNode& _node ) { node = &_node; }
|
||||||
|
/// Copy constructor
|
||||||
|
XMLHandle( const XMLHandle& ref ) { node = ref.node; }
|
||||||
|
/// Assignment
|
||||||
|
XMLHandle operator=( const XMLHandle& ref ) { node = ref.node; return *this; }
|
||||||
|
|
||||||
|
/// Get the first child of this handle.
|
||||||
|
XMLHandle FirstChild() { return XMLHandle( node ? node->FirstChild() : 0 ); }
|
||||||
|
/// Get the first child element of this handle.
|
||||||
|
XMLHandle FirstChildElement( const char* value=0 ) { return XMLHandle( node ? node->FirstChildElement( value ) : 0 ); }
|
||||||
|
/// Get the last child of this handle.
|
||||||
|
XMLHandle LastChild() { return XMLHandle( node ? node->LastChild() : 0 ); }
|
||||||
|
/// Get the last child element of this handle.
|
||||||
|
XMLHandle LastChildElement( const char* _value=0 ) { return XMLHandle( node ? node->LastChildElement( _value ) : 0 ); }
|
||||||
|
/// Get the previous sibling of this handle.
|
||||||
|
XMLHandle PreviousSibling() { return XMLHandle( node ? node->PreviousSibling() : 0 ); }
|
||||||
|
/// Get the previous sibling element of this handle.
|
||||||
|
XMLHandle PreviousSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); }
|
||||||
|
/// Get the next sibling of this handle.
|
||||||
|
XMLHandle NextSibling() { return XMLHandle( node ? node->NextSibling() : 0 ); }
|
||||||
|
/// Get the next sibling element of this handle.
|
||||||
|
XMLHandle NextSiblingElement( const char* _value=0 ) { return XMLHandle( node ? node->NextSiblingElement( _value ) : 0 ); }
|
||||||
|
|
||||||
|
/// Safe cast to XMLNode. This can return null.
|
||||||
|
XMLNode* ToNode() { return node; }
|
||||||
|
/// Safe cast to XMLElement. This can return null.
|
||||||
|
XMLElement* ToElement() { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
|
||||||
|
/// Safe cast to XMLText. This can return null.
|
||||||
|
XMLText* ToText() { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
|
||||||
|
/// Safe cast to XMLUnknown. This can return null.
|
||||||
|
XMLUnknown* ToUnknown() { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
|
||||||
|
/// Safe cast to XMLDeclaration. This can return null.
|
||||||
|
XMLDeclaration* ToDeclaration() { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
XMLNode* node;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
|
||||||
|
same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
|
||||||
|
*/
|
||||||
|
class XMLConstHandle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XMLConstHandle( const XMLNode* _node ) { node = _node; }
|
||||||
|
XMLConstHandle( const XMLNode& _node ) { node = &_node; }
|
||||||
|
XMLConstHandle( const XMLConstHandle& ref ) { node = ref.node; }
|
||||||
|
|
||||||
|
XMLConstHandle operator=( const XMLConstHandle& ref ) { node = ref.node; return *this; }
|
||||||
|
|
||||||
|
const XMLConstHandle FirstChild() const { return XMLConstHandle( node ? node->FirstChild() : 0 ); }
|
||||||
|
const XMLConstHandle FirstChildElement( const char* value=0 ) const { return XMLConstHandle( node ? node->FirstChildElement( value ) : 0 ); }
|
||||||
|
const XMLConstHandle LastChild() const { return XMLConstHandle( node ? node->LastChild() : 0 ); }
|
||||||
|
const XMLConstHandle LastChildElement( const char* _value=0 ) const { return XMLConstHandle( node ? node->LastChildElement( _value ) : 0 ); }
|
||||||
|
const XMLConstHandle PreviousSibling() const { return XMLConstHandle( node ? node->PreviousSibling() : 0 ); }
|
||||||
|
const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const { return XMLConstHandle( node ? node->PreviousSiblingElement( _value ) : 0 ); }
|
||||||
|
const XMLConstHandle NextSibling() const { return XMLConstHandle( node ? node->NextSibling() : 0 ); }
|
||||||
|
const XMLConstHandle NextSiblingElement( const char* _value=0 ) const { return XMLConstHandle( node ? node->NextSiblingElement( _value ) : 0 ); }
|
||||||
|
|
||||||
|
|
||||||
|
const XMLNode* ToNode() const { return node; }
|
||||||
|
const XMLElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
|
||||||
|
const XMLText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
|
||||||
|
const XMLUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
|
||||||
|
const XMLDeclaration* ToDeclaration() const { return ( ( node && node->ToDeclaration() ) ? node->ToDeclaration() : 0 ); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const XMLNode* node;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Printing functionality. The XMLPrinter gives you more
|
Printing functionality. The XMLPrinter gives you more
|
||||||
|
@ -1252,96 +1400,4 @@ private:
|
||||||
} // tinyxml2
|
} // tinyxml2
|
||||||
|
|
||||||
|
|
||||||
// What follows is the docs for the examples.
|
|
||||||
// I'd like the docs to be just before the
|
|
||||||
// actual examples in xmltest.cpp, but I
|
|
||||||
// can't seem to get doxygen to do that. It
|
|
||||||
// would be a wonderful patch if anyone figures
|
|
||||||
// it out.
|
|
||||||
|
|
||||||
/** @page Example-1 Load an XML File
|
|
||||||
* @dontinclude ./xmltest.cpp
|
|
||||||
* Basic XML file loading.
|
|
||||||
* The basic syntax to load an XML file from
|
|
||||||
* disk and check for an error. (ErrorID()
|
|
||||||
* will return 0 for no error.)
|
|
||||||
* @skip example_1()
|
|
||||||
* @until }
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/** @page Example-2 Parse an XML from char buffer
|
|
||||||
* @dontinclude ./xmltest.cpp
|
|
||||||
* Basic XML string parsing.
|
|
||||||
* The basic syntax to parse an XML for
|
|
||||||
* a char* and check for an error. (ErrorID()
|
|
||||||
* will return 0 for no error.)
|
|
||||||
* @skip example_2()
|
|
||||||
* @until }
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @page Example-3 Get information out of XML
|
|
||||||
@dontinclude ./xmltest.cpp
|
|
||||||
In this example, we navigate a simple XML
|
|
||||||
file, and read some interesting text. Note
|
|
||||||
that this is examlpe doesn't use error
|
|
||||||
checking; working code should check for null
|
|
||||||
pointers when walking an XML tree, or use
|
|
||||||
XMLHandle.
|
|
||||||
|
|
||||||
(The XML is an excerpt from "dream.xml").
|
|
||||||
|
|
||||||
@skip example_3
|
|
||||||
@until </PLAY>";
|
|
||||||
|
|
||||||
The structure of the XML file is:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>(declaration)</li>
|
|
||||||
<li>(dtd stuff)</li>
|
|
||||||
<li>Element "PLAY"</li>
|
|
||||||
<ul>
|
|
||||||
<li>Element "TITLE"</li>
|
|
||||||
<ul>
|
|
||||||
<li>Text "A Midsummer Night's Dream"</li>
|
|
||||||
</ul>
|
|
||||||
</ul>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
For this example, we want to print out the
|
|
||||||
title of the play. The text of the title (what
|
|
||||||
we want) is child of the "TITLE" element which
|
|
||||||
is a child of the "PLAY" element.
|
|
||||||
|
|
||||||
We want to skip the declaration and dtd, so the
|
|
||||||
method FirstChildElement() is a good choice. The
|
|
||||||
FirstChildElement() of the Document is the "PLAY"
|
|
||||||
Element, the FirstChildElement() of the "PLAY" Element
|
|
||||||
is the "TITLE" Element.
|
|
||||||
|
|
||||||
@until ( "TITLE" );
|
|
||||||
|
|
||||||
We can then use the convenience function GetText()
|
|
||||||
to get the title of the play.
|
|
||||||
|
|
||||||
@until title );
|
|
||||||
|
|
||||||
Text is just another Node in the XML DOM. And in
|
|
||||||
fact you should be a little cautious with it, as
|
|
||||||
text nodes can contain elements.
|
|
||||||
|
|
||||||
@verbatim
|
|
||||||
Consider: A Midsummer Night's <b>Dream</b>
|
|
||||||
@endverbatim
|
|
||||||
|
|
||||||
It is more correct to actually query the Text Node
|
|
||||||
if in doubt:
|
|
||||||
|
|
||||||
@until title );
|
|
||||||
|
|
||||||
Noting that here we use FirstChild() since we are
|
|
||||||
looking for XMLText, not an element, and ToText()
|
|
||||||
is a cast from a Node to a XMLText.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif // TINYXML2_INCLUDED
|
#endif // TINYXML2_INCLUDED
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
037AE8A4151E692700E0F29F /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 037AE8A1151E692700E0F29F /* tinyxml2.cpp */; };
|
|
||||||
037AE8A5151E692700E0F29F /* xmltest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 037AE8A3151E692700E0F29F /* xmltest.cpp */; };
|
037AE8A5151E692700E0F29F /* xmltest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 037AE8A3151E692700E0F29F /* xmltest.cpp */; };
|
||||||
037AE9BE151E694400E0F29F /* dream.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 037AE062151CCC6D00E0F29F /* dream.xml */; };
|
037AE9BE151E694400E0F29F /* dream.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 037AE062151CCC6D00E0F29F /* dream.xml */; };
|
||||||
037AE9BF151E694400E0F29F /* utf8test.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 037AE065151CCC6D00E0F29F /* utf8test.xml */; };
|
037AE9BF151E694400E0F29F /* utf8test.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 037AE065151CCC6D00E0F29F /* utf8test.xml */; };
|
||||||
037AE9C0151E694400E0F29F /* utf8testverify.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 037AE066151CCC6D00E0F29F /* utf8testverify.xml */; };
|
037AE9C0151E694400E0F29F /* utf8testverify.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 037AE066151CCC6D00E0F29F /* utf8testverify.xml */; };
|
||||||
|
03F28B53152E9B1B00D4CD90 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 03F28B4A152E9B1B00D4CD90 /* tinyxml2.cpp */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
@ -34,9 +34,9 @@
|
||||||
037AE065151CCC6D00E0F29F /* utf8test.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = utf8test.xml; sourceTree = "<group>"; };
|
037AE065151CCC6D00E0F29F /* utf8test.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = utf8test.xml; sourceTree = "<group>"; };
|
||||||
037AE066151CCC6D00E0F29F /* utf8testverify.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = utf8testverify.xml; sourceTree = "<group>"; };
|
037AE066151CCC6D00E0F29F /* utf8testverify.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = utf8testverify.xml; sourceTree = "<group>"; };
|
||||||
037AE86D151E685F00E0F29F /* tinyxml2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tinyxml2; sourceTree = BUILT_PRODUCTS_DIR; };
|
037AE86D151E685F00E0F29F /* tinyxml2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tinyxml2; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
037AE8A1151E692700E0F29F /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxml2.cpp; path = ../tinyxml2.cpp; sourceTree = "<group>"; };
|
|
||||||
037AE8A2151E692700E0F29F /* tinyxml2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinyxml2.h; path = ../tinyxml2.h; sourceTree = "<group>"; };
|
|
||||||
037AE8A3151E692700E0F29F /* xmltest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = xmltest.cpp; path = ../xmltest.cpp; sourceTree = SOURCE_ROOT; };
|
037AE8A3151E692700E0F29F /* xmltest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = xmltest.cpp; path = ../xmltest.cpp; sourceTree = SOURCE_ROOT; };
|
||||||
|
03F28B4A152E9B1B00D4CD90 /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxml2.cpp; sourceTree = "<group>"; };
|
||||||
|
03F28B4B152E9B1B00D4CD90 /* tinyxml2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml2.h; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -53,30 +53,29 @@
|
||||||
037AE056151CCC5200E0F29F = {
|
037AE056151CCC5200E0F29F = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
037AE06A151CCC7C00E0F29F /* resources */,
|
037AE069151CCC7000E0F29F /* Classes */,
|
||||||
037AE069151CCC7000E0F29F /* src */,
|
037AE06A151CCC7C00E0F29F /* Resources */,
|
||||||
|
03F28B60152E9B4C00D4CD90 /* Libraries */,
|
||||||
037AE06F151CCCB900E0F29F /* Products */,
|
037AE06F151CCCB900E0F29F /* Products */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
037AE069151CCC7000E0F29F /* src */ = {
|
037AE069151CCC7000E0F29F /* Classes */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
037AE8A1151E692700E0F29F /* tinyxml2.cpp */,
|
|
||||||
037AE8A2151E692700E0F29F /* tinyxml2.h */,
|
|
||||||
037AE8A3151E692700E0F29F /* xmltest.cpp */,
|
037AE8A3151E692700E0F29F /* xmltest.cpp */,
|
||||||
);
|
);
|
||||||
name = src;
|
name = Classes;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
037AE06A151CCC7C00E0F29F /* resources */ = {
|
037AE06A151CCC7C00E0F29F /* Resources */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
037AE062151CCC6D00E0F29F /* dream.xml */,
|
037AE062151CCC6D00E0F29F /* dream.xml */,
|
||||||
037AE065151CCC6D00E0F29F /* utf8test.xml */,
|
037AE065151CCC6D00E0F29F /* utf8test.xml */,
|
||||||
037AE066151CCC6D00E0F29F /* utf8testverify.xml */,
|
037AE066151CCC6D00E0F29F /* utf8testverify.xml */,
|
||||||
);
|
);
|
||||||
name = resources;
|
name = Resources;
|
||||||
path = ..;
|
path = ..;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
@ -88,6 +87,24 @@
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
03F28AD7152E9B1B00D4CD90 /* tinyxml2 */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
03F28B4A152E9B1B00D4CD90 /* tinyxml2.cpp */,
|
||||||
|
03F28B4B152E9B1B00D4CD90 /* tinyxml2.h */,
|
||||||
|
);
|
||||||
|
name = tinyxml2;
|
||||||
|
path = ..;
|
||||||
|
sourceTree = SOURCE_ROOT;
|
||||||
|
};
|
||||||
|
03F28B60152E9B4C00D4CD90 /* Libraries */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
03F28AD7152E9B1B00D4CD90 /* tinyxml2 */,
|
||||||
|
);
|
||||||
|
name = Libraries;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
@ -138,8 +155,8 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
037AE8A4151E692700E0F29F /* tinyxml2.cpp in Sources */,
|
|
||||||
037AE8A5151E692700E0F29F /* xmltest.cpp in Sources */,
|
037AE8A5151E692700E0F29F /* xmltest.cpp in Sources */,
|
||||||
|
03F28B53152E9B1B00D4CD90 /* tinyxml2.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
38
xmltest.cpp
38
xmltest.cpp
|
@ -751,6 +751,44 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
||||||
XMLTest( "Clone and Equal", 4, count );
|
XMLTest( "Clone and Equal", 4, count );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// This shouldn't crash.
|
||||||
|
XMLDocument doc;
|
||||||
|
if(XML_NO_ERROR != doc.LoadFile( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))
|
||||||
|
{
|
||||||
|
doc.PrintError();
|
||||||
|
}
|
||||||
|
XMLTest( "Error in snprinf handling.", true, doc.Error() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------- Handles ------------
|
||||||
|
{
|
||||||
|
static const char* xml = "<element attrib='bar'><sub>Text</sub></element>";
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.Parse( xml );
|
||||||
|
|
||||||
|
XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement();
|
||||||
|
XMLTest( "Handle, success, mutable", ele->Value(), "sub" );
|
||||||
|
|
||||||
|
XMLHandle docH( doc );
|
||||||
|
ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
|
||||||
|
XMLTest( "Handle, dne, mutable", false, ele != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
static const char* xml = "<element attrib='bar'><sub>Text</sub></element>";
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.Parse( xml );
|
||||||
|
XMLConstHandle docH( doc );
|
||||||
|
|
||||||
|
const XMLElement* ele = docH.FirstChildElement( "element" ).FirstChild().ToElement();
|
||||||
|
XMLTest( "Handle, success, const", ele->Value(), "sub" );
|
||||||
|
|
||||||
|
ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
|
||||||
|
XMLTest( "Handle, dne, const", false, ele != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------- Performance tracking --------------
|
// ----------- Performance tracking --------------
|
||||||
{
|
{
|
||||||
#if defined( _MSC_VER )
|
#if defined( _MSC_VER )
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
// Purely doxygen documentation
|
||||||
|
|
||||||
|
|
||||||
|
// What follows is the docs for the examples.
|
||||||
|
// I'd like the docs to be just before the
|
||||||
|
// actual examples in xmltest.cpp, but I
|
||||||
|
// can't seem to get doxygen to do that. It
|
||||||
|
// would be a wonderful patch if anyone figures
|
||||||
|
// it out.
|
||||||
|
|
||||||
|
/** @page Example-1 Load an XML File
|
||||||
|
* @dontinclude ./xmltest.cpp
|
||||||
|
* Basic XML file loading.
|
||||||
|
* The basic syntax to load an XML file from
|
||||||
|
* disk and check for an error. (ErrorID()
|
||||||
|
* will return 0 for no error.)
|
||||||
|
* @skip example_1()
|
||||||
|
* @until }
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @page Example-2 Parse an XML from char buffer
|
||||||
|
* @dontinclude ./xmltest.cpp
|
||||||
|
* Basic XML string parsing.
|
||||||
|
* The basic syntax to parse an XML for
|
||||||
|
* a char* and check for an error. (ErrorID()
|
||||||
|
* will return 0 for no error.)
|
||||||
|
* @skip example_2()
|
||||||
|
* @until }
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @page Example-3 Get information out of XML
|
||||||
|
@dontinclude ./xmltest.cpp
|
||||||
|
In this example, we navigate a simple XML
|
||||||
|
file, and read some interesting text. Note
|
||||||
|
that this is examlpe doesn't use error
|
||||||
|
checking; working code should check for null
|
||||||
|
pointers when walking an XML tree, or use
|
||||||
|
XMLHandle.
|
||||||
|
|
||||||
|
(The XML is an excerpt from "dream.xml").
|
||||||
|
|
||||||
|
@skip example_3
|
||||||
|
@until </PLAY>";
|
||||||
|
|
||||||
|
The structure of the XML file is:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>(declaration)</li>
|
||||||
|
<li>(dtd stuff)</li>
|
||||||
|
<li>Element "PLAY"</li>
|
||||||
|
<ul>
|
||||||
|
<li>Element "TITLE"</li>
|
||||||
|
<ul>
|
||||||
|
<li>Text "A Midsummer Night's Dream"</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
For this example, we want to print out the
|
||||||
|
title of the play. The text of the title (what
|
||||||
|
we want) is child of the "TITLE" element which
|
||||||
|
is a child of the "PLAY" element.
|
||||||
|
|
||||||
|
We want to skip the declaration and dtd, so the
|
||||||
|
method FirstChildElement() is a good choice. The
|
||||||
|
FirstChildElement() of the Document is the "PLAY"
|
||||||
|
Element, the FirstChildElement() of the "PLAY" Element
|
||||||
|
is the "TITLE" Element.
|
||||||
|
|
||||||
|
@until ( "TITLE" );
|
||||||
|
|
||||||
|
We can then use the convenience function GetText()
|
||||||
|
to get the title of the play.
|
||||||
|
|
||||||
|
@until title );
|
||||||
|
|
||||||
|
Text is just another Node in the XML DOM. And in
|
||||||
|
fact you should be a little cautious with it, as
|
||||||
|
text nodes can contain elements.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
Consider: A Midsummer Night's <b>Dream</b>
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
It is more correct to actually query the Text Node
|
||||||
|
if in doubt:
|
||||||
|
|
||||||
|
@until title );
|
||||||
|
|
||||||
|
Noting that here we use FirstChild() since we are
|
||||||
|
looking for XMLText, not an element, and ToText()
|
||||||
|
is a cast from a Node to a XMLText.
|
||||||
|
*/
|
Loading…
Reference in New Issue