2015-11-14 5 views
4

Определенная задача требует от меня анализа XML-файла и проверки каждого узла и его атрибутов. Я провел несколько недель, изучая XML и XML-синтаксический анализ. Я даже воспользовался более ранними вопросами, связанными с разбором LIBXML в C, и на основе этого понимания я написал этот код ниже. Но этот код ошибочен, поскольку я не достигаю цели.Как получить атрибут в XML с помощью библиотеки libxml c?

Я думаю, что я перепутал концепцию родительского ребенка и сестры. Что я понял из ниже упомянутого файла XML является то, что:

Профиль является корневой узел и каталог являются его дети и Каталог имеет детей в качестве параметров и Параметр имеет детей, как Target и все каталог узлов друг друга братьями и сестрами ,

Profile--> Catalog--> Parameter-->Target 
     |-> Catalog--> Parameter-->Target 

Но когда я пытаюсь перейти от каталога к параметру, перемещая указатель на указатель детей узла каталогов, я м не в состоянии пойти. И так как я не могу достичь параметра I m, который не может попасть в цель.

Поблагодарите исправление в моем понимании и кодексе. P.S Мое требование - код на C, поэтому, пожалуйста, не указывайте меня на другой язык.

/***** 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; 
    } 
+0

Почему никто не отвечает ?? – Albert

ответ

3

Мой недавний понимание XML DOM работает отлично, и он говорит, что все атрибуты элемента представлены в DOM как дочерние узлы этого элемента. Так что, если сделать DOM из выше XML мы увидим:

      Profile 
    ___________________________|____________________ 
    |  |   |  |   |   | 
date origin version catalog1 catalog2 catalog3 
    __________________________| 
    |    |   | 
parameter version   id 
    |_________________________________________ 
    |   |  |   |   | 
    name  value applytype reboot  target 
            __________| 
            |   | 
           instance  class 

И catalog2 и catalog3 также будут иметь их детей. Основываясь на этом DOM, если я написал функцию get_next_node и get_children_node, и он отлично работает для меня.

/** 
* get the children node and skip any non xml element node 
* 
* @param xml node 
* @param xml children node 
* 
* @return xmlNodePtr children of xml node 
*/ 

static void xmlGetNodeChildren(xmlNodePtr xmlNode, xmlNodePtr *childrenNode) 
{ 
     xmlNodePtr node = NULL; 

     node = xmlNode->children; 
     while (node->type != XML_ELEMENT_NODE) 
     { 
     node = node->next; 
     if (node == NULL) 
     { 
      break; 
     } 
     } 

     *childrenNode = node; 
} 


/** 
* get the next node and skip any non xml element node 
* such as text and comment node 
* 
* @param xml node 
* @param xml next node 
*/ 
static void xmlGetNodeNext(xmlNodePtr *xmlNode) 
{ 
    xmlNodePtr node = NULL; 

    node = (*xmlNode)->next; 
    while (node->type != XML_ELEMENT_NODE) 
    { 
     node=node->next; 
     if (node == NULL) 
     { 
      break; 
     } 
    } 
    *xmlNode = node; 
} 
+1

Возможно, вы захотите использовать 'xmlFirstElementChild' и' xmlNextElementSibling'. – so61pi

Смежные вопросы