Parse XML using XMLParsher.h in C

Post date: May 5, 2011 3:25:36 AM

Let's assume that you want to parse the XML file "PMMLModel.xml" that contains:

<?xml version="1.0" encoding="ISO-8859-1"?>

<PMML version="3.0"

  xmlns="http://www.dmg.org/PMML-3-0"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema_instance" >

  <Header copyright="Frank Vanden Berghen">      Hello World!

     <Application name="&lt;Condor>" version="1.99beta" />

  </Header>   <Extension name="keys"> <Key name="urn"> </Key> </Extension>

  <DataDictionary>

    <DataField name="persfam" optype="continuous" dataType="double">

       <Value value="9.900000e+001" property="missing" />

    </DataField>

    <DataField name="prov" optype="continuous" dataType="double" />

    <DataField name="urb" optype="continuous" dataType="double" />

    <DataField name="ses" optype="continuous" dataType="double" />

  </DataDictionary>

  <RegressionModel functionName="regression" modelType="linearRegression">

    <RegressionTable intercept="0.00796037">

      <NumericPredictor name="persfam" coefficient="-0.00275951" />

      <NumericPredictor name="prov" coefficient="0.000319433" />

      <NumericPredictor name="ses" coefficient="-0.000454307" />       <NONNumericPredictor name="testXmlExample" />

    </RegressionTable>

  </RegressionModel>

</PMML>

Let's analyse line by line the following small example program:

#include <stdio.h>    // to get "printf" function #include <stdlib.h>   // to get "free" function #include "xmlParser.h"  int main(int argc, char **argv) {   // this open and parse the XML file:

  XMLNode xMainNode=XMLNode::openFileHelper("PMMLModel.xml","PMML");

   // this prints "<Condor>":   XMLNode xNode=xMainNode.getChildNode("Header");   printf("Application Name is: '%s'\n", 

        xNode.getChildNode("Application").getAttribute("name"));

     // this prints "Hello world!":   printf("Text inside Header tag is :'%s'\n", xNode.getText());

   // this gets the number of "NumericPredictor" tags:

  xNode=xMainNode.getChildNode("RegressionModel").getChildNode("RegressionTable");   int n=xNode.nChildNode("NumericPredictor");    // this prints the "coefficient" value for all the "NumericPredictor" tags:

  for (int i=0; i<n; i++)     printf("coeff %i=%f\n",i+1,

        atof(xNode.getChildNode("NumericPredictor",i).getAttribute("coefficient")));    // this prints a formatted ouput based on the 

content of the first "Extension" tag of the XML file:

  char *t=xMainNode.getChildNode("Extension").createXMLString(true);

  printf("%s\n",t);

  free(t);   return 0;

}

To manipulate the data contained inside the XML file, the first operation is to get an instance of the class XMLNode that is representing the XML file in memory. You can use:

XMLNode xMainNode=XMLNode::openFileHelper("PMMLModel.xml","PMML");

or, if you use the UNICODE windows version of the library:

XMLNode xMainNode=XMLNode::openFileHelper("PMMLModel.xml",_T("PMML"));

or, if the XML document is already in a memory buffer pointed by variable "char *xmlDoc" :

XMLNode xMainNode=XMLNode::parseString(xmlDoc,"PMML");

This will create an object called xMainNode that represents the first tag named PMML found inside the XML document. This object is the top of tree structure representing the XML file in memory. The following command creates a new object called xNode that represents the "Header" tag inside the "PMML" tag.

XMLNode xNode=xMainNode.getChildNode("Header");

The following command prints on the screen "<Condor>" (note that the "&lt;" character entity has been replaced by "<"):

printf("Application Name is: '%S'\n", 

        xNode.getChildNode("Application").getAttribute("name"));

The following command prints on the screen "Hello World!":

printf("Text inside Header tag is :'%s'\n", xNode.getText());

Let's assume you want to "go to" the tag named "RegressionTable":

xNode=xMainNode.getChildNode("RegressionModel").getChildNode("RegressionTable");

Note that the previous value of the object named xNode has been "garbage collected" so that no memory leak occurs. If you want to know how many tags named "NumericPredictor" are contained inside the tag named "RegressionTable":

int n=xNode.nChildNode("NumericPredictor");

The variable n now contains the value 3. If you want to print the value of the coefficient attribute for all the NumericPredictor tags:

for (int i=0; i<n; i++)   printf("coeff %i=%f\n",i+1,

    atof(xNode.getChildNode("NumericPredictor",i).getAttribute("coefficient")));

Or equivalently, but faster at runtime:

int iterator=0; for (int i=0; i<n; i++)   printf("coeff %i=%f\n",i+1,

    atof(xNode.getChildNode("NumericPredictor",&iterator).getAttribute("coefficient")));

If you want to generate and print on the screen the following XML formatted text:

<Extension name="keys">   <Key name="urn" /> </Extension> 

You can use:

char *t=xMainNode.getChildNode("Extension").createXMLString(true);

printf("%s\n",t);

free(t);

Note that you must free the memory yourself (using the "free(t);" function) : only the XMLNode objects and their contents are "garbage collected". The parameter true to the function createXMLString means that we want formatted output.

The XML Parser library contains many more other small usefull methods that are not described here (The zip file contains some additional examples to explain other functionalities). These methods allows you to:

That's all folks! With this basic knowledge, you should be able to retreive easily any data from any XML file!