The TiXmlDocument::Parse() function incorrectly returns 0. This is an annoyance since I need to try reading the file to validate a successfull load. I am loading a file from one of two methods, either an xml string retrieved from the registry, or a file which may or may not contain xml data. In either case, the Parse method is used.
When reading from a file, I first read into a byte array and pass this to the Parse method. This works as expected. But when dynamicaly building a string, it seems to parse correctly, but a further call to Parse from within the main Parse() returns an empty string (not NULL). This later cause a call to SkipWhiteSpace() to return 0, setting 'p' to 0 breaking the loop. 'p = 0' is then returned, making it appear like the parsing failed and there is no xml data.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
if ( doc.LoadFile(lpIn) )
{
root = doc.RootElement();
if ( ! root ) {
return false;
}
node = root->FirstChildElement("Region");
if ( node )
{
country = (char*)node->ToElement()->Attribute("Country");
province = (char*)node->ToElement()->Attribute("Province");
city = (char*)node->ToElement()->Attribute("City");
}
element = root->FirstChildElement("Name");
if ( element )
{
enName = (char*)element->GetText();
}
element = root->FirstChildElement("ChName");
if ( element )
{
chName = (char*)element->GetText();
}
if (country) _mbscpy((unsigned char*)lpBuf[i].szCountry, (unsigned char*)country);
if (province) _mbscpy((unsigned char*)lpBuf[i].szProvince, (unsigned char*)province);
if (city) _mbscpy((unsigned char*)lpBuf[i].szCity, (unsigned char*)city);
if (enName) _mbscpy((unsigned char*)lpBuf[i].szName, (unsigned char*)enName);
if (chName) _mbscpy((unsigned char*)lpBuf[i].szChineseName, (unsigned char*)chName);
}
The TiXmlDocument::Parse() function incorrectly returns 0. This is an annoyance since I need to try reading the file to validate a successfull load. I am loading a file from one of two methods, either an xml string retrieved from the registry, or a file which may or may not contain xml data. In either case, the Parse method is used.
When reading from a file, I first read into a byte array and pass this to the Parse method. This works as expected. But when dynamicaly building a string, it seems to parse correctly, but a further call to Parse from within the main Parse() returns an empty string (not NULL). This later cause a call to SkipWhiteSpace() to return 0, setting 'p' to 0 breaking the loop. 'p = 0' is then returned, making it appear like the parsing failed and there is no xml data.
Would you mind posting a self-contained small repeatable demonstration of this?
Sure, though I must point out adding a newline char to the end of the string solves the problem. But it really shouldn't be necessary.
TiXmlDocument doc;
TiXmlNode* node = 0;
TiXmlElement* root = 0;
TiXmlElement* element = 0;
char *country = NULL;
char *province = NULL;
char *city = NULL;
char *enName = NULL;
char *chName = NULL;
char *lpIn;
bool bUsedFile = false;
if ( doc.LoadFile(lpIn) )
{
root = doc.RootElement();
if ( ! root ) {
return false;
}
node = root->FirstChildElement("Region");
if ( node )
{
country = (char*)node->ToElement()->Attribute("Country");
province = (char*)node->ToElement()->Attribute("Province");
city = (char*)node->ToElement()->Attribute("City");
}
element = root->FirstChildElement("Name");
if ( element )
{
enName = (char*)element->GetText();
}
element = root->FirstChildElement("ChName");
if ( element )
{
chName = (char*)element->GetText();
}
if (country) _mbscpy((unsigned char*)lpBuf[i].szCountry, (unsigned char*)country);
if (province) _mbscpy((unsigned char*)lpBuf[i].szProvince, (unsigned char*)province);
if (city) _mbscpy((unsigned char*)lpBuf[i].szCity, (unsigned char*)city);
if (enName) _mbscpy((unsigned char*)lpBuf[i].szName, (unsigned char*)enName);
if (chName) _mbscpy((unsigned char*)lpBuf[i].szChineseName, (unsigned char*)chName);
}
And the xml string is as follows:
#define REGISTRY_XML _SC("<?xml version=\"1.0\" encoding=\"utf-8\" ?>")\ _SC("<GameSettings>")\ _SC("<Region Country=\"%s\" Province=\"%s\" City=\"%s\" />")\ _SC("<Name>%s</Name>")\ _SC("<ChName>%s</ChName>")\ _SC("<Hash>%s</Hash>")\ _SC("</GameSettings>\n")
Parse() doesn't *incorrectly* return 0, it just has a confusing interface. The correct way to parse a string is:
TiXmlDocument doc;
doc.Parse( str );
if ( doc.Error() ) // do error handling
...the return value of Parse() isn't usually meaningful.
lee