Sign in to follow this  

TinyXML: I do not have a clue

This topic is 4485 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I have spent today and yesterday trying to get coax my application to read XML files utilizing TinyXML but currently having no luck. I simply do not know how to proceed invoking the parser to begin going through and extracting data. So far I have the following:
//~~~~~Load Data Attributes Files
    TiXmlDocument PlayerUnitAttrib("Data/Objects/PlayerUnits.xml");
    PlayerUnitAttrib.LoadFile();
    if(PlayerUnitAttrib.Error() && PlayerUnitAttrib.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE) 
    {
        MessageBox(hwnd, "XML Parser Error", "Could not load file: PlayerUnits.xml", MB_OK | MB_ICONEXCLAMATION);
        return false;
    }

//~~~~~Allocate and Parse Data into Application
    TiXmlHandle hPlayerUnitAttrib(&PlayerUnitAttrib);


I do not know how to go from there, say if I was reading from the text below:
...
<Body>
  <Unit ID="1">
    <Name>Xiachunyi</Name>
    <Data>2000</Data>
  </Unit>
</Body>
...
I have looked at the example(s) provided by TinyXML and Gamedev but it still confuses me. Can anyone explain to me or point me in another direction as to what I am to do to read from a parent, child, sibling, and attribute? Thank you.

Share this post


Link to post
Share on other sites

Maybe you'll find this code usefull, it's extracted from my game's sources.




// create new document
TiXmlDocument xmlDoc(levelName.c_str());

// error handling
if (!xmlDoc.LoadFile())
{
string tmp("Couldn't load level from file: ");
tmp += levelName;
tmp += ", reason: ";
tmp += xmlDoc.ErrorDesc();
logError2("Game", tmp.c_str());
xmlDoc.Clear();
return false;
}

// "Level" is the main, root tag of our file
TiXmlElement * root = xmlDoc.FirstChildElement("Level");

if (!root)
{
logError2(levelName.c_str(), "Not found root 'Level' tag.");
xmlDoc.Clear();
return false;
}


// iterate through all found "Entity" tags
for (const TiXmlElement * itor = _xmlStream->FirstChildElement("Entity"); itor; itor = itor->NextSiblingElement("Entity"))
{
// if tag has attribute which value equals "Platform", that is it looks like this:
// <Entity Type="Plarform">
if (!strcmp(itor->Attribute("Type"), "Platform"))
{
// create it
TPlatform * newPlatform = new TPlatform;

if (!newPlatform)
{
logError2("Game", "Critical: Couldn't allocate memory for new Platform.")
continue;
}

if (!newPlatform->Create(itor)) // implementation of this function can be found later
return false;

platforms.push_back(newPlatform);
}
}

// ...


bool TPlatform :: Create(const TiXmlElement * _xmlStream)
{

// obtain pointer to "Shadow" tag, which is child node of _xmlStream, ie:
// <Entity Type="Platform">
// <Shadow>
const TiXmlElement * xmlShadowTag = _xmlStream->FirstChildElement("Shadow");

// if it's non zero, then use it, otherwise - we have error
if (xmlShadowTag)
{
// once again, obtain pointer to tag "Offset" which is child of "Shadow" tag:
// <Entity Type="Platform">
// <Shadow>
// <Offset>
const TiXmlElement * xmlOffsetTag = xmlShadowTag->FirstChildElement("Offset");

if (xmlOffsetTag)
{
shadowOffset.x = GetTagValueSlint(xmlOffsetTag, "x");
shadowOffset.y = GetTagValueSlint(xmlOffsetTag, "y");
hasShadow = true;
}

shadowTransparency = GetTagValueSlint(xmlShadowTag, "Transparency");

}



There are a lots of comments, so ideally you should be able to get a grasp of how to parse XMLs. One note though: I'm not using handles.

Other functions which I find handy. They can be used as a quick n' dirty method of obtaining value from tags:


// ------------------------------------------------- start GetTagValueTxt

const char * SC :: GetTagValueTxt(const TiXmlElement * _xmlStream, const char * _tagName)
{
const TiXmlElement * tag = _xmlStream->FirstChildElement(_tagName);

if (tag)
{
const TiXmlNode * node = tag->FirstChild();

if (node)
{
const TiXmlText * value = node->ToText();
if (value) return (value->Value());
else return 0;
} else return 0;
} else return 0;

}

// ------------------------------------------------- end GetTagValueTxt

// ------------------------------------------------- start GetTagValueTxt

const char * SC :: GetTagValueTxt(const TiXmlElement * _xmlStream)
{
if (_xmlStream)
{
const TiXmlNode * node = _xmlStream->FirstChild();

if (node)
{
const TiXmlText * value = node->ToText();
if (value) return (value->Value());
else return 0;

} else return 0;
}
else return 0;
}

// ------------------------------------------------- end GetTagValueTxt

// ------------------------------------------------- start GetTagValueSlint

SC :: slint SC :: GetTagValueSlint(const TiXmlElement * _xmlStream, const char * _tagName, slint _default)
{
const TiXmlElement * tag = _xmlStream->FirstChildElement(_tagName);

if (tag)
{
const TiXmlNode * node = tag->FirstChild();

if (node)
{
const TiXmlText * value = node->ToText();
if (value) return atoi(value->Value());
else return _default;
} else return _default;
} else return _default;
}

// ------------------------------------------------- end GetTagValueSlint

// ------------------------------------------------- start GetTagValueFloat

float SC :: GetTagValueFloat(const TiXmlElement * _xmlStream, const char * _tagName, float _default)
{
const TiXmlElement * tag = _xmlStream->FirstChildElement(_tagName);

if (tag)
{
const TiXmlNode * node = tag->FirstChild();

if (node)
{
const TiXmlText * value = node->ToText();
if (value) return atof(value->Value());
else return _default;
} else return _default;
} else return _default;
}

// ------------------------------------------------- end GetTagValueFloat



HTH :-)

Share this post


Link to post
Share on other sites
No prob :-)

One thing I forgot to add in previous mail is the documentation of functions:


//! From <_tagName> valueText </_tagName> returns valueText. _tagName is tag inside _xmlStream.
const char * GetTagValueTxt(const TiXmlElement * _xmlStream, const char * _tagName);

//! Directly from _xmlStream returns text value that is have, or 0 if it doesn't exist.
const char * GetTagValueTxt(const TiXmlElement * _xmlStream);


//! From <_tagName> valueSlint </_tagName> returns converted valueSlint.
//! \param _default will be returned if any error has occured.
slint GetTagValueSlint(const TiXmlElement * _xmlStream, const char * _tagName, slint _default = 0);


//! From <_tagName> valueFloat </_tagName> returns converted valueFloat.
//! \param _default will be returned if any error has occured.
float GetTagValueFloat(const TiXmlElement * _xmlStream, const char * _tagName, float _default = 0);


Share this post


Link to post
Share on other sites

This topic is 4485 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this