4

yester day was my first attempt. I am trying to catch the variable "time" in the following "new.xml" file

<?xml version="1.0" standalone=no>
<main>
 <ToDo time="1">
  <Item priority="1"> Go to the <bold>Toy store!</bold></Item>
  <Item priority="2"> Do bills</Item>
 </ToDo>
 <ToDo time="2">
  <Item priority="1"> Go to the Second<bold>Toy store!</bold></Item>
 </ToDo>
</main>

Here is my code

TiXmlDocument doc("new.xml");
TiXmlNode * element=doc.FirstChild("main");
element=element->FirstChild("ToDo");
string temp=static_cast<TiXmlElement *>(element)->Attribute("time");

But I am getting run time errors from the third and fourth lines. Can anybody shed a light on this isssue?

MSalters
  • 173,980
  • 10
  • 155
  • 350
prabhakaran
  • 5,126
  • 17
  • 71
  • 107

3 Answers3

2

It seems to me that you forgot to load the file. Normally I do something along these lines:

TiXmlDocument doc("document.xml");
bool loadOkay = doc.LoadFile(); // Error checking in case file is missing
if(loadOkay)
{
    TiXmlElement *pRoot = doc.RootElement();
    TiXmlElement *element = pRoot->FirstChildElement();
    while(element)
    {
        string value = firstChild->Value(); // In your example xml file this gives you ToDo
        string attribute = firstChild->Attribute("time"); //Gets you the time variable
        element = element->NextSiblingElement();
    }
}
else
{
    //Error conditions
} 

Hope this helps

BOMEz
  • 1,020
  • 14
  • 34
0
#include "tinyXml/tinyxml.h"

const char MY_XML[] = "<?xml version='1.0' standalone=no><main> <ToDo time='1'>  <Item priority='1'> Go to the <bold>Toy store!</bold></Item>  <Item priority='2'> Do bills</Item> </ToDo> <ToDo time='2'>  <Item priority='1'> Go to the Second<bold>Toy store!</bold></Item> </ToDo></main>";

void main()
{
    TiXmlDocument doc;
    TiXmlHandle docHandle(&doc);

    const char * const the_xml = MY_XML;
    doc.Parse(MY_XML);

    TiXmlElement* xElement = NULL;
    xElement = docHandle.FirstChild("main").FirstChild("ToDo").ToElement();

    int element_time = -1;

    while(xElement)
    {
        if(xElement->QueryIntAttribute("time", (int*)&element_time) != TIXML_SUCCESS)
            throw;

        xElement = xElement->NextSiblingElement();
    }
}

That's how it works. Compiled & tested.
As you can see your tries to make it extra-safe code cost you with an exceotion at your third line (of the question), and without testing I can bet it's a "pointing-to-null" exception.

Just load it my style, as TinyXml's docs say as well: "docHandle.FirstChild("main").FirstChild("ToDo").ToElement();".

Hope it helps you understand, let me know if it's not clear. I accept visa (:

Poni
  • 11,061
  • 25
  • 80
  • 121
0

Is it just me or the the pugixml version looks much better?

#include <iostream>
#include "pugixml.hpp"

using namespace std;
using namespace pugi;

int main()
{   
    xml_document doc;
    if (!doc.load_file("new.xml"))
    {
        cerr << "Could not load xml";
        return 1;
    }
    xml_node element = doc.child("main");
    element = element.child("ToDo");

    cout << "Time: " << element.attribute("time") << endl;
}

Also new.xml had an error, instead of:

<?xml version="1.0" standalone=no>

should be

<?xml version="1.0" standalone="no"?>

Compilation was just a matter of cl test.cpp pugixml.cpp

Cristian Adam
  • 4,749
  • 22
  • 19
  • 1
    Due to the fact that I am in shortage of time for my current project, I am not able to check your idea. But, thank you for it. Definitely I will check it. – prabhakaran Nov 13 '10 at 11:59