Jump to content
  • Advertisement
Sign in to follow this  
ratha

XML Parsing using Tiny XML

This topic is 2610 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

Hi!
I've to parse an XML File using Tiny XML. My XML file contents are:


<?xml version="1.0"?>
<request>
<properties name ="TicketID">T5jkbec7i2f410m</properties>
<Form1Buttons>Login,Reset,Exit</Form1Buttons>
</request>


I've to pass "TicketID" and get the result as "T5jkbec7i2f410m". Also I've to pass "Form1Buttons" and get "Login,Reset,Exit" as result.

I've used the following code:

I've used the following code:

const char* common::Parse_XML_Document(char* filename, char* tagname)
{
TiXmlDocument * tiDoc = new TiXmlDocument(filename);
TiXmlElement * tiElement = new TiXmlElement(tagname);
const char * value = new char[1024];
//TiXmlAttribute * tiAttribute = new TiXmlElement(tagname);
if(tiDoc->LoadFile())
{
value = tiElement->GetText();
}
return value;
}


But value contains only a BadPtr. How to pass the XML file name and the tag name and retrieve the value of that tag?

Share this post


Link to post
Share on other sites
Advertisement
I haven't used TinyXML in awhile, but I think you need to do something like:

TiXmlElement* root = tiDoc->GetRootElement();
for (TiXmlElement* elm = root->FirstChildElement(tagname); elm != 0; elm = elm->NextSiblingElement()) {
const char* value = elm->GetText();
}


Also, IIRC, TinyXML returns ptrs to strings it allocates. You don't have to create buffers for them.

Share this post


Link to post
Share on other sites
I got the following error:

[size="1"]error C2039: 'GetRootElement' : is not a member of 'TiXmlDocument'



Share this post


Link to post
Share on other sites
I do something like:



TiXmlDocument doc(fileName);
if (!doc.LoadFile()) { return false; }
TiXmlHandle hDoc(&doc);
TiXmlNode *node= hDoc.FirstChildElement().Node();
if(!node) { return false; }
TiXmlNode *request = node->FirstChild("request");
if(!request) { return false; }
std::string text; // perhaps text is an out value
if(!GetText(text, request >FirstChild("Form1Buttons"))) { return false; }

return true;

Where GetText is a helper function:

bool GetText(std::string &out, TiXmlNode *xmlNode)
{
if(!xmlNode) { return false; }
TiXmlElement *element = xmlNode->ToElement();
if(!element) { return false; }
out = element->GetText();
return true;
}


If you have multiple requests then use the IterateChildren methods.
You currently have memory leaks in yours (new but no delete). Just use actual objects (or shared pointer) instead of allocating them with new as there is probably quite a few reasons reading may fail and you don't want to have to clean up on each if.



Share this post


Link to post
Share on other sites
Your problem has little to do with TinyXML and all with why you should be using std::string in the first place (also I can only guess you come from a Java background from all the new's and memory leaks)

TiXmlDocument * tiDoc = new TiXmlDocument(filename);

TiXmlElement * tiElement = new TiXmlElement(tagname);

You allocate two objects with new and the only pointers are on the stack and lost when you exit the function -> memory leak
Also: what is tiElement supposed to be? You create a new Element in no way associated to the document (which isn't even loaded yet) with undefined (or default constructed) content which is pretty definitely not going to be a string, so trying to get it's value as a string can only result in a null pointer.

Even if this did what you probably think it does: when there could be any number of tagname nodes in a document, how would tinyxml know which one you want?

const char * value = new char[1024];
[font="Arial"]
You create a buffer, value points to this buffer

[/font][font="Arial"]You assign a ptr to a most likely internal string to value and create a neat memory leak of 1024 byte

You return this pointer to a most likely internal string.[/font]



string func()
{
const char* txt = 0;
TiXmlDocument xml(filename);
if (xml.LoadFile())
{
if ( TiXmlElement* e = xml.RootElement()->FirstChildElement(tagname) )
txt = e->GetText();
}
return string( txt ? txt : "not found");
}


If you have multiple tags of that name or they are not direct children of the root node, you have to first search for the element.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!