4

I don't know how to read this xml file using tinyxml2 in C++

<?xml version="1.0" encoding="utf-8"?>
<empleados>
 <cantidad>UnaCantidad</cantidad>
 <empleado>
  <idEmpleado>1</idEmpleado>
  <nombre>UnNombre1</nombre>
  <apellidos>UnosApellidos1</apellidos>
 </empleado>
 <empleado>
  <idEmpleado>2</idEmpleado>
  <nombre>UnNombre2</nombre>
  <apellidos>UnosApellidos2</apellidos>
 </empleado>
</empleados> 

This is what I'm doing now, is not working:

tinyxml2::XMLDocument xml_doc;

tinyxml2::XMLError eResult = xml_doc.LoadFile(xml_path);
XMLCheckResult(eResult);

tinyxml2::XMLNode* root = xml_doc.FirstChild();
if (root == nullptr) return tinyxml2::XML_ERROR_FILE_READ_ERROR;

tinyxml2::XMLElement* element = root->FirstChildElement("cantidad");
if (element == nullptr) return tinyxml2::XML_ERROR_PARSING_ELEMENT;

int xml_count;
eResult = element->QueryIntText(&xml_count);
XMLCheckResult(eResult);

Empleado* empleados= Empleado[xml_count];

element = root->FirstChildElement("empleado");
Empleado e;
int i = 0;

while (element != nullptr && i < xml_count)
{
    tinyxml2::XMLElement* item = element->FirstChildElement("idEmpleado");
    int id;
    eResult = item->QueryIntText(&id);
    XMLCheckResult(eResult);

    item = element->FirstChildElement("nombre");
    string nombre = item->Gettext();

    item = element->FirstChildElement("apellidos");
    string apellidos = item->Gettext(); 

    e = Empleado();
    e.id = id;
    e.nombre = nombre;
    e.apellidos = apellidos;
    empleados[i] = e;

    element = element->NextSiblingElement("empleado");
    i++;
}

When I try to get the first XMLElement (cantidad) I obtain a nullptr. What is that I'm doing wrong, please help me...

manlio
  • 18,345
  • 14
  • 76
  • 126
fbr
  • 98
  • 1
  • 1
  • 9
  • What exactly is the problem? It is easy to find the sample of using tinyxml http://www.grinninglizard.com/tinyxml2docs/_example-3.html – demonplus Apr 03 '15 at 16:29
  • @demonplus I edited the original post to show you the problem. – fbr Apr 03 '15 at 17:12

1 Answers1

6

It is because FirstChild was getting you the XML header.

Here is a simplified example of what you are doing:

#include "tinyxml2.h"

bool Test()
{
   tinyxml2::XMLDocument xml_doc;

   tinyxml2::XMLError eResult = xml_doc.LoadFile("test.xml");
   if (eResult != tinyxml2::XML_SUCCESS) return false;

   tinyxml2::XMLNode* root = xml_doc.FirstChild();
   if (root == nullptr) return false;

   tinyxml2::XMLElement* element = root->FirstChildElement("cantidad");
   if (element == nullptr) return false;//Fails here

   return true;
}

int main()
{
   Test();
}

And it fails where indicated. Here is that part now working:

#include "tinyxml2.h"

bool Test()
{
   tinyxml2::XMLDocument xml_doc;

   tinyxml2::XMLError eResult = xml_doc.LoadFile("test.xml");
   if (eResult != tinyxml2::XML_SUCCESS) return false;

   tinyxml2::XMLNode* root = xml_doc.FirstChildElement("empleados");
   if (root == nullptr) return false;

   tinyxml2::XMLElement* element = root->FirstChildElement("cantidad");
   if (element == nullptr) return false;

   return true;
}

int main()
{
   Test();
}

It works because instead of FirstChild it gets the child by name. I don't know about the rest; but now that you have that you should be fine from there.

Hope that helps!

A.J.
  • 325
  • 1
  • 4