mirror of https://github.com/AxioDL/tinyxml2.git
Moving string in/out into XMLUtil. Using that across the API. Supporting text queries of primitive types.
This commit is contained in:
parent
78a773ddd9
commit
21be882810
|
@ -10,7 +10,7 @@ include(GNUInstallDirs)
|
|||
################################
|
||||
# set lib version here
|
||||
|
||||
set(GENERIC_LIB_VERSION "1.0.5")
|
||||
set(GENERIC_LIB_VERSION "1.0.6")
|
||||
set(GENERIC_LIB_SOVERSION "1")
|
||||
|
||||
|
||||
|
|
2
dox
2
dox
|
@ -32,7 +32,7 @@ PROJECT_NAME = "TinyXML-2"
|
|||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 1.0.5
|
||||
PROJECT_NUMBER = 1.0.6
|
||||
|
||||
# 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
|
||||
|
|
235
tinyxml2.cpp
235
tinyxml2.cpp
|
@ -369,6 +369,86 @@ const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
|
|||
}
|
||||
|
||||
|
||||
void XMLUtil::ToStr( int v, char* buffer, int bufferSize )
|
||||
{
|
||||
TIXML_SNPRINTF( buffer, bufferSize, "%d", v );
|
||||
}
|
||||
|
||||
|
||||
void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize )
|
||||
{
|
||||
TIXML_SNPRINTF( buffer, bufferSize, "%u", v );
|
||||
}
|
||||
|
||||
|
||||
void XMLUtil::ToStr( bool v, char* buffer, int bufferSize )
|
||||
{
|
||||
TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 );
|
||||
}
|
||||
|
||||
|
||||
void XMLUtil::ToStr( float v, char* buffer, int bufferSize )
|
||||
{
|
||||
TIXML_SNPRINTF( buffer, bufferSize, "%f", v );
|
||||
}
|
||||
|
||||
|
||||
void XMLUtil::ToStr( double v, char* buffer, int bufferSize )
|
||||
{
|
||||
TIXML_SNPRINTF( buffer, bufferSize, "%f", v );
|
||||
}
|
||||
|
||||
|
||||
bool XMLUtil::ToInt( const char* str, int* value )
|
||||
{
|
||||
if ( TIXML_SSCANF( str, "%d", value ) == 1 )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XMLUtil::ToUnsigned( const char* str, unsigned *value )
|
||||
{
|
||||
if ( TIXML_SSCANF( str, "%u", value ) == 1 )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XMLUtil::ToBool( const char* str, bool* value )
|
||||
{
|
||||
int ival = 0;
|
||||
if ( ToInt( str, &ival )) {
|
||||
*value = (ival==0) ? false : true;
|
||||
return true;
|
||||
}
|
||||
if ( StringEqual( str, "true" ) ) {
|
||||
*value = true;
|
||||
return true;
|
||||
}
|
||||
else if ( StringEqual( str, "false" ) ) {
|
||||
*value = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool XMLUtil::ToFloat( const char* str, float* value )
|
||||
{
|
||||
if ( TIXML_SSCANF( str, "%f", value ) == 1 ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XMLUtil::ToDouble( const char* str, double* value )
|
||||
{
|
||||
if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
char* XMLDocument::Identify( char* p, XMLNode** node )
|
||||
{
|
||||
XMLNode* returnNode = 0;
|
||||
|
@ -942,7 +1022,7 @@ void XMLAttribute::SetName( const char* n )
|
|||
|
||||
int XMLAttribute::QueryIntValue( int* value ) const
|
||||
{
|
||||
if ( TIXML_SSCANF( Value(), "%d", value ) == 1 )
|
||||
if ( XMLUtil::ToInt( Value(), value ))
|
||||
return XML_NO_ERROR;
|
||||
return XML_WRONG_ATTRIBUTE_TYPE;
|
||||
}
|
||||
|
@ -950,7 +1030,7 @@ int XMLAttribute::QueryIntValue( int* value ) const
|
|||
|
||||
int XMLAttribute::QueryUnsignedValue( unsigned int* value ) const
|
||||
{
|
||||
if ( TIXML_SSCANF( Value(), "%u", value ) == 1 )
|
||||
if ( XMLUtil::ToUnsigned( Value(), value ))
|
||||
return XML_NO_ERROR;
|
||||
return XML_WRONG_ATTRIBUTE_TYPE;
|
||||
}
|
||||
|
@ -958,32 +1038,24 @@ int XMLAttribute::QueryUnsignedValue( unsigned int* value ) const
|
|||
|
||||
int XMLAttribute::QueryBoolValue( bool* value ) const
|
||||
{
|
||||
int ival = -1;
|
||||
QueryIntValue( &ival );
|
||||
|
||||
if ( ival > 0 || XMLUtil::StringEqual( Value(), "true" ) ) {
|
||||
*value = true;
|
||||
if ( XMLUtil::ToBool( Value(), value )) {
|
||||
return XML_NO_ERROR;
|
||||
}
|
||||
else if ( ival == 0 || XMLUtil::StringEqual( Value(), "false" ) ) {
|
||||
*value = false;
|
||||
return XML_NO_ERROR;
|
||||
}
|
||||
return XML_WRONG_ATTRIBUTE_TYPE;
|
||||
}
|
||||
|
||||
|
||||
int XMLAttribute::QueryDoubleValue( double* value ) const
|
||||
{
|
||||
if ( TIXML_SSCANF( Value(), "%lf", value ) == 1 )
|
||||
return XML_NO_ERROR;
|
||||
return XML_WRONG_ATTRIBUTE_TYPE;
|
||||
}
|
||||
|
||||
|
||||
int XMLAttribute::QueryFloatValue( float* value ) const
|
||||
{
|
||||
if ( TIXML_SSCANF( Value(), "%f", value ) == 1 )
|
||||
if ( XMLUtil::ToFloat( Value(), value ))
|
||||
return XML_NO_ERROR;
|
||||
return XML_WRONG_ATTRIBUTE_TYPE;
|
||||
}
|
||||
|
||||
|
||||
int XMLAttribute::QueryDoubleValue( double* value ) const
|
||||
{
|
||||
if ( XMLUtil::ToDouble( Value(), value ))
|
||||
return XML_NO_ERROR;
|
||||
return XML_WRONG_ATTRIBUTE_TYPE;
|
||||
}
|
||||
|
@ -998,7 +1070,7 @@ void XMLAttribute::SetAttribute( const char* v )
|
|||
void XMLAttribute::SetAttribute( int v )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v );
|
||||
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||
value.SetStr( buf );
|
||||
}
|
||||
|
||||
|
@ -1006,7 +1078,7 @@ void XMLAttribute::SetAttribute( int v )
|
|||
void XMLAttribute::SetAttribute( unsigned v )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
TIXML_SNPRINTF( buf, BUF_SIZE, "%u", v );
|
||||
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||
value.SetStr( buf );
|
||||
}
|
||||
|
||||
|
@ -1014,21 +1086,21 @@ void XMLAttribute::SetAttribute( unsigned v )
|
|||
void XMLAttribute::SetAttribute( bool v )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v ? 1 : 0 );
|
||||
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||
value.SetStr( buf );
|
||||
}
|
||||
|
||||
void XMLAttribute::SetAttribute( double v )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
TIXML_SNPRINTF( buf, BUF_SIZE, "%f", v );
|
||||
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||
value.SetStr( buf );
|
||||
}
|
||||
|
||||
void XMLAttribute::SetAttribute( float v )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
TIXML_SNPRINTF( buf, BUF_SIZE, "%f", v );
|
||||
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||
value.SetStr( buf );
|
||||
}
|
||||
|
||||
|
@ -1093,6 +1165,72 @@ const char* XMLElement::GetText() const
|
|||
}
|
||||
|
||||
|
||||
int XMLElement::QueryIntText( int* _value ) const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
const char* t = FirstChild()->ToText()->Value();
|
||||
if ( XMLUtil::ToInt( t, _value ) ) {
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
return XML_CAN_NOT_CONVERT_TEXT;
|
||||
}
|
||||
return XML_NO_TEXT_NODE;
|
||||
}
|
||||
|
||||
|
||||
int XMLElement::QueryUnsignedText( unsigned* _value ) const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
const char* t = FirstChild()->ToText()->Value();
|
||||
if ( XMLUtil::ToUnsigned( t, _value ) ) {
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
return XML_CAN_NOT_CONVERT_TEXT;
|
||||
}
|
||||
return XML_NO_TEXT_NODE;
|
||||
}
|
||||
|
||||
|
||||
int XMLElement::QueryBoolText( bool* _value ) const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
const char* t = FirstChild()->ToText()->Value();
|
||||
if ( XMLUtil::ToBool( t, _value ) ) {
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
return XML_CAN_NOT_CONVERT_TEXT;
|
||||
}
|
||||
return XML_NO_TEXT_NODE;
|
||||
}
|
||||
|
||||
|
||||
int XMLElement::QueryDoubleText( double* _value ) const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
const char* t = FirstChild()->ToText()->Value();
|
||||
if ( XMLUtil::ToDouble( t, _value ) ) {
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
return XML_CAN_NOT_CONVERT_TEXT;
|
||||
}
|
||||
return XML_NO_TEXT_NODE;
|
||||
}
|
||||
|
||||
|
||||
int XMLElement::QueryFloatText( float* _value ) const
|
||||
{
|
||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||
const char* t = FirstChild()->ToText()->Value();
|
||||
if ( XMLUtil::ToFloat( t, _value ) ) {
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
return XML_CAN_NOT_CONVERT_TEXT;
|
||||
}
|
||||
return XML_NO_TEXT_NODE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )
|
||||
{
|
||||
XMLAttribute* last = 0;
|
||||
|
@ -1668,7 +1806,7 @@ void XMLPrinter::PushAttribute( const char* name, const char* value )
|
|||
void XMLPrinter::PushAttribute( const char* name, int v )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v );
|
||||
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||
PushAttribute( name, buf );
|
||||
}
|
||||
|
||||
|
@ -1676,7 +1814,7 @@ void XMLPrinter::PushAttribute( const char* name, int v )
|
|||
void XMLPrinter::PushAttribute( const char* name, unsigned v )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
TIXML_SNPRINTF( buf, BUF_SIZE, "%u", v );
|
||||
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||
PushAttribute( name, buf );
|
||||
}
|
||||
|
||||
|
@ -1684,7 +1822,7 @@ void XMLPrinter::PushAttribute( const char* name, unsigned v )
|
|||
void XMLPrinter::PushAttribute( const char* name, bool v )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
TIXML_SNPRINTF( buf, BUF_SIZE, "%d", v ? 1 : 0 );
|
||||
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||
PushAttribute( name, buf );
|
||||
}
|
||||
|
||||
|
@ -1692,7 +1830,7 @@ void XMLPrinter::PushAttribute( const char* name, bool v )
|
|||
void XMLPrinter::PushAttribute( const char* name, double v )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
TIXML_SNPRINTF( buf, BUF_SIZE, "%f", v );
|
||||
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||
PushAttribute( name, buf );
|
||||
}
|
||||
|
||||
|
@ -1745,6 +1883,45 @@ void XMLPrinter::PushText( const char* text, bool cdata )
|
|||
}
|
||||
}
|
||||
|
||||
void XMLPrinter::PushText( int value )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
XMLUtil::ToStr( value, buf, BUF_SIZE );
|
||||
PushText( buf, false );
|
||||
}
|
||||
|
||||
|
||||
void XMLPrinter::PushText( unsigned value )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
XMLUtil::ToStr( value, buf, BUF_SIZE );
|
||||
PushText( buf, false );
|
||||
}
|
||||
|
||||
|
||||
void XMLPrinter::PushText( bool value )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
XMLUtil::ToStr( value, buf, BUF_SIZE );
|
||||
PushText( buf, false );
|
||||
}
|
||||
|
||||
|
||||
void XMLPrinter::PushText( float value )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
XMLUtil::ToStr( value, buf, BUF_SIZE );
|
||||
PushText( buf, false );
|
||||
}
|
||||
|
||||
|
||||
void XMLPrinter::PushText( double value )
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
XMLUtil::ToStr( value, buf, BUF_SIZE );
|
||||
PushText( buf, false );
|
||||
}
|
||||
|
||||
|
||||
void XMLPrinter::PushComment( const char* comment )
|
||||
{
|
||||
|
|
76
tinyxml2.h
76
tinyxml2.h
|
@ -85,7 +85,7 @@ distribution.
|
|||
|
||||
static const int TIXML2_MAJOR_VERSION = 1;
|
||||
static const int TIXML2_MINOR_VERSION = 0;
|
||||
static const int TIXML2_PATCH_VERSION = 5;
|
||||
static const int TIXML2_PATCH_VERSION = 6;
|
||||
|
||||
namespace tinyxml2
|
||||
{
|
||||
|
@ -388,6 +388,20 @@ public:
|
|||
// the UTF-8 value of the entity will be placed in value, and length filled in.
|
||||
static const char* GetCharacterRef( const char* p, char* value, int* length );
|
||||
static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
|
||||
|
||||
// converts primitive types to strings
|
||||
static void ToStr( int v, char* buffer, int bufferSize );
|
||||
static void ToStr( unsigned v, char* buffer, int bufferSize );
|
||||
static void ToStr( bool v, char* buffer, int bufferSize );
|
||||
static void ToStr( float v, char* buffer, int bufferSize );
|
||||
static void ToStr( double v, char* buffer, int bufferSize );
|
||||
|
||||
// converts strings to primitive types
|
||||
static bool ToInt( const char* str, int* value );
|
||||
static bool ToUnsigned( const char* str, unsigned* value );
|
||||
static bool ToBool( const char* str, bool* value );
|
||||
static bool ToFloat( const char* str, float* value );
|
||||
static bool ToDouble( const char* str, double* value );
|
||||
};
|
||||
|
||||
|
||||
|
@ -739,7 +753,10 @@ enum {
|
|||
XML_ERROR_PARSING_UNKNOWN,
|
||||
XML_ERROR_EMPTY_DOCUMENT,
|
||||
XML_ERROR_MISMATCHED_ELEMENT,
|
||||
XML_ERROR_PARSING
|
||||
XML_ERROR_PARSING,
|
||||
|
||||
XML_CAN_NOT_CONVERT_TEXT,
|
||||
XML_NO_TEXT_NODE
|
||||
};
|
||||
|
||||
|
||||
|
@ -928,7 +945,7 @@ public:
|
|||
This is a convenient method for getting the text of simple contained text:
|
||||
@verbatim
|
||||
<foo>This is text</foo>
|
||||
const char* str = fooElement->GetText();
|
||||
const char* str = fooElement->GetText();
|
||||
@endverbatim
|
||||
|
||||
'str' will be a pointer to "This is text".
|
||||
|
@ -936,18 +953,54 @@ public:
|
|||
Note that this function can be misleading. If the element foo was created from
|
||||
this XML:
|
||||
@verbatim
|
||||
<foo><b>This is text</b></foo>
|
||||
<foo><b>This is text</b></foo>
|
||||
@endverbatim
|
||||
|
||||
then the value of str would be null. The first child node isn't a text node, it is
|
||||
another element. From this XML:
|
||||
@verbatim
|
||||
<foo>This is <b>text</b></foo>
|
||||
<foo>This is <b>text</b></foo>
|
||||
@endverbatim
|
||||
GetText() will return "This is ".
|
||||
*/
|
||||
const char* GetText() const;
|
||||
|
||||
/**
|
||||
Convenience method to query the value of a child text node. This is probably best
|
||||
shown by example. Given you have a document is this form:
|
||||
@verbatim
|
||||
<point>
|
||||
<x>1</x>
|
||||
<y>1.4</y>
|
||||
</point>
|
||||
@endverbatim
|
||||
|
||||
The QueryIntText() and similar functions provide a safe and easier way to get to the
|
||||
"value" of x and y.
|
||||
|
||||
@verbatim
|
||||
int x = 0;
|
||||
float y = 0; // types of x and y are contrived for example
|
||||
const XMLElement* xElement = pointElement->FirstChildElement( "x" );
|
||||
const XMLElement* yElement = pointElement->FirstChildElement( "y" );
|
||||
xElement->QueryIntText( &x );
|
||||
yElement->QueryFloatText( &y );
|
||||
@endverbatim
|
||||
|
||||
@returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
|
||||
to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.
|
||||
|
||||
*/
|
||||
int QueryIntText( int* _value ) const;
|
||||
/// See QueryIntText()
|
||||
int QueryUnsignedText( unsigned* _value ) const;
|
||||
/// See QueryIntText()
|
||||
int QueryBoolText( bool* _value ) const;
|
||||
/// See QueryIntText()
|
||||
int QueryDoubleText( double* _value ) const;
|
||||
/// See QueryIntText()
|
||||
int QueryFloatText( float* _value ) const;
|
||||
|
||||
// internal:
|
||||
enum {
|
||||
OPEN, // <foo>
|
||||
|
@ -1352,7 +1405,18 @@ public:
|
|||
|
||||
/// Add a text node.
|
||||
void PushText( const char* text, bool cdata=false );
|
||||
/// Add a comment.
|
||||
/// Add a text node from an integer.
|
||||
void PushText( int value );
|
||||
/// Add a text node from an unsigned.
|
||||
void PushText( unsigned value );
|
||||
/// Add a text node from a bool.
|
||||
void PushText( bool value );
|
||||
/// Add a text node from a float.
|
||||
void PushText( float value );
|
||||
/// Add a text node from a double.
|
||||
void PushText( double value );
|
||||
|
||||
/// Add a comment
|
||||
void PushComment( const char* comment );
|
||||
|
||||
void PushDeclaration( const char* value );
|
||||
|
|
85
xmltest.cpp
85
xmltest.cpp
|
@ -38,7 +38,7 @@ bool XMLTest (const char* testString, const char* expected, const char* found, b
|
|||
}
|
||||
|
||||
|
||||
bool XMLTest( const char* testString, int expected, int found, bool echo=true )
|
||||
template< class T > bool XMLTest( const char* testString, T expected, T found, bool echo=true )
|
||||
{
|
||||
bool pass = ( expected == found );
|
||||
if ( pass )
|
||||
|
@ -116,6 +116,34 @@ int example_3()
|
|||
}
|
||||
|
||||
|
||||
bool example_4()
|
||||
{
|
||||
static const char* xml =
|
||||
"<information>"
|
||||
" <attributeApproach v='2' />"
|
||||
" <textApproach>"
|
||||
" <v>2</v>"
|
||||
" </textApproach>"
|
||||
"</information>";
|
||||
|
||||
XMLDocument doc;
|
||||
doc.Parse( xml );
|
||||
|
||||
int v0 = 0;
|
||||
int v1 = 0;
|
||||
|
||||
XMLElement* attributeApproachElement = doc.FirstChildElement()->FirstChildElement( "attributeApproach" );
|
||||
attributeApproachElement->QueryIntAttribute( "v", &v0 );
|
||||
|
||||
XMLElement* textApproachElement = doc.FirstChildElement()->FirstChildElement( "textApproach" );
|
||||
textApproachElement->FirstChildElement( "v" )->QueryIntText( &v1 );
|
||||
|
||||
printf( "Both values are the same: %d and %d\n", v0, v1 );
|
||||
|
||||
return !doc.Error() && ( v0 == v1 );
|
||||
}
|
||||
|
||||
|
||||
int main( int /*argc*/, const char ** /*argv*/ )
|
||||
{
|
||||
#if defined( _MSC_VER ) && defined( DEBUG )
|
||||
|
@ -148,6 +176,7 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
|||
XMLTest( "Example-1", 0, example_1() );
|
||||
XMLTest( "Example-2", 0, example_2() );
|
||||
XMLTest( "Example-3", 0, example_3() );
|
||||
XMLTest( "Example-4", true, example_4() );
|
||||
|
||||
/* ------ Example 2: Lookup information. ---- */
|
||||
|
||||
|
@ -243,7 +272,7 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
|||
XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) );
|
||||
int value = 10;
|
||||
int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value );
|
||||
XMLTest( "Programmatic DOM", result, XML_NO_ATTRIBUTE );
|
||||
XMLTest( "Programmatic DOM", result, (int)XML_NO_ATTRIBUTE );
|
||||
XMLTest( "Programmatic DOM", value, 10 );
|
||||
|
||||
doc->Print();
|
||||
|
@ -303,7 +332,7 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
|||
|
||||
XMLDocument doc;
|
||||
doc.Parse( error );
|
||||
XMLTest( "Bad XML", doc.ErrorID(), XML_ERROR_PARSING_ATTRIBUTE );
|
||||
XMLTest( "Bad XML", doc.ErrorID(), (int)XML_ERROR_PARSING_ATTRIBUTE );
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -318,17 +347,17 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
|||
double dVal;
|
||||
|
||||
result = ele->QueryDoubleAttribute( "attr0", &dVal );
|
||||
XMLTest( "Query attribute: int as double", result, XML_NO_ERROR );
|
||||
XMLTest( "Query attribute: int as double", result, (int)XML_NO_ERROR );
|
||||
XMLTest( "Query attribute: int as double", (int)dVal, 1 );
|
||||
result = ele->QueryDoubleAttribute( "attr1", &dVal );
|
||||
XMLTest( "Query attribute: double as double", (int)dVal, 2 );
|
||||
result = ele->QueryIntAttribute( "attr1", &iVal );
|
||||
XMLTest( "Query attribute: double as int", result, XML_NO_ERROR );
|
||||
XMLTest( "Query attribute: double as int", result, (int)XML_NO_ERROR );
|
||||
XMLTest( "Query attribute: double as int", iVal, 2 );
|
||||
result = ele->QueryIntAttribute( "attr2", &iVal );
|
||||
XMLTest( "Query attribute: not a number", result, XML_WRONG_ATTRIBUTE_TYPE );
|
||||
XMLTest( "Query attribute: not a number", result, (int)XML_WRONG_ATTRIBUTE_TYPE );
|
||||
result = ele->QueryIntAttribute( "bar", &iVal );
|
||||
XMLTest( "Query attribute: does not exist", result, XML_NO_ATTRIBUTE );
|
||||
XMLTest( "Query attribute: does not exist", result, (int)XML_NO_ATTRIBUTE );
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -566,7 +595,7 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
|||
|
||||
XMLDocument doc;
|
||||
doc.Parse( test );
|
||||
XMLTest( "dot in names", doc.Error(), 0);
|
||||
XMLTest( "dot in names", doc.Error(), false );
|
||||
XMLTest( "dot in names", doc.FirstChildElement()->Name(), "a.elem" );
|
||||
XMLTest( "dot in names", doc.FirstChildElement()->Attribute( "xmi.version" ), "2.0" );
|
||||
}
|
||||
|
@ -623,7 +652,7 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
|||
XMLDocument doc;
|
||||
doc.Parse( doctype );
|
||||
|
||||
XMLTest( "Parsing repeated attributes.", XML_ERROR_PARSING_ATTRIBUTE, doc.ErrorID() ); // is an error to tinyxml (didn't use to be, but caused issues)
|
||||
XMLTest( "Parsing repeated attributes.", (int)XML_ERROR_PARSING_ATTRIBUTE, doc.ErrorID() ); // is an error to tinyxml (didn't use to be, but caused issues)
|
||||
doc.PrintError();
|
||||
}
|
||||
|
||||
|
@ -641,7 +670,7 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
|||
const char* str = " ";
|
||||
XMLDocument doc;
|
||||
doc.Parse( str );
|
||||
XMLTest( "Empty document error", XML_ERROR_EMPTY_DOCUMENT, doc.ErrorID() );
|
||||
XMLTest( "Empty document error", (int)XML_ERROR_EMPTY_DOCUMENT, doc.ErrorID() );
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -668,7 +697,7 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
|||
xml.Parse("<x> ");
|
||||
XMLTest("Missing end tag with trailing whitespace", xml.Error(), true);
|
||||
xml.Parse("<x></y>");
|
||||
XMLTest("Mismatched tags", xml.ErrorID(), XML_ERROR_MISMATCHED_ELEMENT);
|
||||
XMLTest("Mismatched tags", xml.ErrorID(), (int)XML_ERROR_MISMATCHED_ELEMENT);
|
||||
}
|
||||
|
||||
|
||||
|
@ -865,6 +894,40 @@ int main( int /*argc*/, const char ** /*argv*/ )
|
|||
XMLTest( "BOM and default declaration", printer.CStr(), result, false );
|
||||
XMLTest( "CStrSize", printer.CStrSize(), 42, false );
|
||||
}
|
||||
{
|
||||
const char* xml = "<ipxml ws='1'><info bla=' /></ipxml>";
|
||||
XMLDocument doc;
|
||||
doc.Parse( xml );
|
||||
XMLTest( "Ill formed XML", true, doc.Error() );
|
||||
}
|
||||
|
||||
// QueryXYZText
|
||||
{
|
||||
const char* xml = "<point> <x>1.2</x> <y>1</y> <z>38</z> <valid>true</valid> </point>";
|
||||
XMLDocument doc;
|
||||
doc.Parse( xml );
|
||||
|
||||
const XMLElement* pointElement = doc.RootElement();
|
||||
|
||||
int intValue = 0;
|
||||
unsigned unsignedValue = 0;
|
||||
float floatValue = 0;
|
||||
double doubleValue = 0;
|
||||
bool boolValue = false;
|
||||
|
||||
pointElement->FirstChildElement( "y" )->QueryIntText( &intValue );
|
||||
pointElement->FirstChildElement( "y" )->QueryUnsignedText( &unsignedValue );
|
||||
pointElement->FirstChildElement( "x" )->QueryFloatText( &floatValue );
|
||||
pointElement->FirstChildElement( "x" )->QueryDoubleText( &doubleValue );
|
||||
pointElement->FirstChildElement( "valid" )->QueryBoolText( &boolValue );
|
||||
|
||||
|
||||
XMLTest( "QueryIntText", intValue, 1, false );
|
||||
XMLTest( "QueryUnsignedText", unsignedValue, (unsigned)1, false );
|
||||
XMLTest( "QueryFloatText", floatValue, 1.2f, false );
|
||||
XMLTest( "QueryDoubleText", doubleValue, 1.2, false );
|
||||
XMLTest( "QueryBoolText", boolValue, true, false );
|
||||
}
|
||||
|
||||
|
||||
// ----------- Performance tracking --------------
|
||||
|
|
35
xmltest.h
35
xmltest.h
|
@ -92,3 +92,38 @@
|
|||
looking for XMLText, not an element, and ToText()
|
||||
is a cast from a Node to a XMLText.
|
||||
*/
|
||||
|
||||
/** @page Example-4 Read attributes and text information.
|
||||
@dontinclude ./xmltest.cpp
|
||||
|
||||
There are fundamentally 2 ways of writing a key-value
|
||||
pair into an XML file. (Something that's always annoyed
|
||||
me about XML.) Either by using attributes, or by writing
|
||||
the key name into an element and the value into
|
||||
the text node wrapped by the element. Both approaches
|
||||
are illustrated in this example, which shows two ways
|
||||
to encode the value "2" into the key "v":
|
||||
|
||||
@skip example_4
|
||||
@until "</information>";
|
||||
|
||||
TinyXML-2 has accessors for both approaches.
|
||||
|
||||
When using an attribute, you navigate to the XMLElement
|
||||
with that attribute and use the QueryIntAttribute()
|
||||
group of methods. (Also QueryFloatAttribute(), etc.)
|
||||
|
||||
@skip XMLElement* attributeApproachElement
|
||||
@until &v0 );
|
||||
|
||||
When using the text approach, you need to navigate
|
||||
down one more step to the XMLElement that contains
|
||||
the text. Note the extra FirstChildElement( "v" )
|
||||
in the code below. The value of the text can then
|
||||
be safely queried with the QueryIntText() group
|
||||
of methods. (Also QueryFloatText(), etc.)
|
||||
|
||||
@skip XMLElement* textApproachElement
|
||||
@until &v1 );
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue