2015-11-14 51 views
4

某个任务需要我解析一个XML文件并检查每个节点及其属性。我花了几周的时间学习XML和XML解析。我甚至在C语言中发布了与LIBXML解析相关的早期问题的帮助,并且基于这种理解,我在下面编写了这些代码。但是这个代码是有缺陷的,因为我没有达到目标。如何使用libxml c库获取XML中的属性?

我想我已经搞砸了一些父母的孩子和兄弟姐妹的概念。 我从下面提到的XML文件明白的是:

档案是根节点和目录的是其子女和 目录有孩子作为参数,并 参数有孩子的目标 和所有的目录节点互为兄弟姐妹。

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

但是当我试图通过移动指针目录孩子节点指针从目录去参数,我不是能去。因为我无法达到参数我不能去目标。

希望能在我的理解和代码中加以纠正。 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中表示为该元素的子节点。因此,如果制作上述XML的DOM,我们将看到:

      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

相关问题