A specific task requires me to parse an XML file and validate each node and its attributes. I spent several weeks studying XML and XML parsing. I even took advantage of earlier questions related to parsing LIBXML in C, and based on this understanding, I wrote this code below. But this code is wrong, as I am not achieving the goal.
I think I messed up the concept of parent child and sister. What I understand from the XML file below is as follows:
The profile is the root of the node, and the directory is its children, and there are children in the catalog as Parameters and the Parameter has children as Target and all the nodes in the catalog are siblings.
Profile--> Catalog--> Parameter-->Target
|-> Catalog--> Parameter-->Target
But when I try to move from the Directory to the Parameter by moving the pointer to the directory children node pointer, I cannot go. And since I can’t reach the parameter I m, which cannot hit the target.
Thank you for the correction in my understanding and code. PS My requirement is to code in C, so please do not point me to another language.
<?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);
if ((doc = xmlReadFile(argv[1], NULL, 0)) == NULL){
printf("error: could not parse file %s\n", argv[1]);
exit(-1);
}
root_element = xmlDocGetRootElement(doc);
print_element_names(doc, root_element);
xmlFreeDoc(doc);
xmlCleanupParser();
return 0;
}