A certain task requires me to parse an XML file and check every node and its attributes. I have spent few weeks learning XML and XML parsing. I have even taken the help of earlier questions posted related to LIBXML parsing in C and based on that understanding I have written this code below. But this code is flawed as I doesn't achieve the objective.
I think I have messed up some parent child and sibling concept. What i understand from the below mentioned XML file is that:
Profile is the Root node and Catalog's are its children and Catalog has children as Parameters and Parameter has children as Target and all catalog nodes are each other siblings.
Profile--> Catalog--> Parameter-->Target
|-> Catalog--> Parameter-->Target
But when i try to go from Catalog to Parameter by moving the pointer to Catalogs children node pointer, I m not able to go. And as i m not able to reach Parameter I m not able to go to target.
Would appreciate correction in my understanding and Code. P.S My requirement is to code in C, so please don't point me to other language.
/***** MY XML FILE ***************************/
<?xml version="1.0" encoding="UTF-8"?>
<!-- When VIOS level changes, the value of ioslevel needs to change manually -->
<Profile origin="get" version="3.0.0" date="2012-10-05T00:00:00Z">
<Catalog1 id="devParam" version="3.0">
<Parameter1 name="policy" value="single" applyType="boot" reboot="true">
<Target1 class="device" instance="disk1"/>
</Parameter1>
</Catalog1>
<Catalog2 id="devParam" version="3.0">
<Parameter2 name="policy" value="no" applyType="boot">
<Target2 class="device" instance="disk2"/>
</Parameter2>
</Catalog2>
<Catalog3 id="devParam" version="3.0">
<Parameter3 name="policy" value="no" applyType="nextboot" reboot="true">
<Target3 class="device" instance="disk3"/>
</Parameter3>
</Catalog3>
</Profile>
/****************************************************************/
#include <string.h>
#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
static void print_element_names(xmlDoc *doc, xmlNode * profile_node)
{
xmlNode *catalog_node = NULL, *parameter_node = NULL, *target_node = NULL, *tmp_node = NULL;
xmlChar *instance=NULL, *key=NULL;
if (xmlStrcmp(profile_node->name, (const xmlChar *) "Profile")) {
fprintf(stderr,"document of the wrong type, root node != story");
xmlFreeDoc(doc);
return;
}
for (catalog_node = profile_node->xmlChildrenNode; catalog_node; catalog_node =catalog_node->next)
{
if (catalog_node->type == XML_ELEMENT_NODE)
{
printf("Catalog %s \t type %d \n",catalog_node->name, catalog_node->type);
for(parameter_node = catalog_node->xmlChildrenNode; parameter_node; parameter_node = parameter_node->next)
{
if (parameter_node->type == XML_ELEMENT_NODE)
{
printf("Parameter %s \t type %d \n",parameter_node->name, parameter_node->type);
for( target_node=parameter_node->xmlChildrenNode->next; target_node; target_node=target_node->next)
{
printf("Target %s \t type %d \t",target_node->name, target_node->type);
if((target_node->type == XML_ELEMENT_NODE)&&(!strcmp(target_node->name, (const xmlChar *)"Target")))
{
instance_attr = xmlGetProp(inner_child, "instance");
printf("instance_attr = %s\n",instance_attr);
}
}
}
}
}
}
}
int main(int argc, char **argv)
{
xmlDoc *doc = NULL;
xmlNode *root_element = NULL;
if (argc != 2) return(1);
/*parse the file and get the DOM */
if ((doc = xmlReadFile(argv[1], NULL, 0)) == NULL){
printf("error: could not parse file %s\n", argv[1]);
exit(-1);
}
/*Get the root element node */
root_element = xmlDocGetRootElement(doc);
print_element_names(doc, root_element);
xmlFreeDoc(doc); /* free document*/
xmlCleanupParser(); /*/ Free globals*/
return 0;
}