2015-11-14 52 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

相關問題