XML DOM Parser

Dear Root People,
I’m trying to use the XML Parser inserted in Root, but I’m experiencing some troubles.
I try to explain you what I would like to do. I am describing the
geometry of a telescope with a xml file. My telescope is defined by a
set of modules.
In my main file, when i build the Telescope, I have these lines:

TDOMParser *domParser = new TDOMParser(); domParser->SetValidate(false); Int_t parsecode = domParser->ParseFile(inTelfile); if (parsecode < 0) { cerr << domParser->GetParseCodeMessage(parsecode) << endl; return -1; } TXMLNode *xTelescope = domParser->GetXMLDocument()->GetRootNode(); Telescope MyTelescope(xTelescope);

Then the Telescope class has a constructor that call a function called
ParseTelescope that reads the xml file. Here is the function I wrote:

void ParseTelescope(TXMLNode *XMLin) { if (strcmp(XMLin->GetNodeName(), "TELESCOPE") == 0) { TList *attrList = XMLin->GetAttributes(); TXMLAttr *attr = 0; TIter next(attrList); while ((attr=(TXMLAttr*)next())) { if (strcmp(attr->GetName(), "No_OM") == 0) { NumberOfModules = atoi(attr->GetValue()); cout<<"Reading The Telescope: No of OM = "<<NumberOfModules<<endl; break; } if(strcmp(XMLin->GetChildren()->GetNodeName(), "MOD") == 0 ){ for (int i=0; i < NumberOfModules; i++) { push_back(new Abstract_Module(XMLin->GetChildren())); } } } } }

The first part is working fine, but what it doesn’t work and I cannot
understand why, it the GetChildren().
I want to read what is in the “MOD” node. But if I call
XMLin->GetChildren()->GetNodeName() it returns the string “text”, and I
don’t understand why. What should I do to pass from “TELESCOPE” to “MOD”?
Please, help!

First lines of the xml file:

[code]<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>

30 4.705 -0.525 453.863 -0.78028 0 [/code]

Hi, Ellyon

That you observe is a feature of libxml2 parser. When it decodes XML data with child structure, it always inserts dummy text node between two real child nodes even if there is no text at all. It is done because following XML code is valid too:

Therefore, in your case, you should call XMLin->GetChildren()->GetNextNode()->GetNodeName()

Actually, I do not recommend you to rely on this feature of libxml2 parser. Normally you should always iterate over all children nodes and search for node via its name.


Thank you very much!
I am thinking actually to change my class in order to profit better of the root classes. In particular I would like to use the loop over the children nodes, do you think that I can do it easily? in the example the PersonList, that correspond to my Telescope is a TList of Persons, while my Telescope is a Vector of Modules… Do you think I better change it in TList, or I can do it equally with the vector class?

Hi, Eleonora

It is up to you to use vector (TObjArray or TClonesArray) or list (TList) in your code. Generally, you should use vectors when you need fast random access to items in your containers. When you need frequently insert/delete items, list containers is more adequate.

Only when you performs XML I/O, you will converts any kind of containers to/from hierarchical structure of XML nodes, which internally builds of list of nodes.

By the way, together with libxml2 parser ROOT provides generic method to convert any kind of instrumented classes to/from XML files. You probably, can look into http://root.cern.ch/root/htmldoc/TXMLFile.html functionality.

Regards, Sergey