解析XML文件并写入链表

时间:2017-12-02 07:13:10

标签: c linked-list xml-parsing

我正在尝试解析XML数据并将其保存在链接列表中,该列表应该在启动时加载到主内存中。解析XML数据时,我希望在链表的一个节点和下一个节点中的下一组数据中写入一组XML实体/元素。在尝试实现这一点时,我能够解析我需要的数据,但是由于我尝试应用的逻辑似乎不正确,因此将数据分配给链表并不会发生。我想要一些帮助。

File.xml

<policyList>
        <policySecurity>
                <policyName>AutoAdd</policyName>
                <deviceName>PA-722</deviceName>
                <status>ACTIVE</status>
                <srcZone>any</srcZone>
                <dstZone>any</dstZone>
                <srcAddr>any</srcAddr>
                <dstAddr>5.5.5.4</dstAddr>
                <srcUser>any</srcUser>
                <application>any</application>
                <service>any</service>
                <urlCategory>any</urlCategory>
                <action>deny</action>
        </policySecurity>
        <policySecurity>
                <policyName>Test-1</policyName>
                <deviceName>PA-710</deviceName>
                <status>ACTIVE</status>
                <srcZone>any</srcZone>
                <dstZone>any</dstZone>
                <srcAddr>192.168.1.23</srcAddr>
                <dstAddr>8.8.8.8</dstAddr>
                <srcUser>vivek</srcUser>
                <application>any</application>
                <service>any</service>
                <urlCategory>any</urlCategory>
                <action>deny</action>
        </policySecurity>
</policyList>

File.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/parser.h>


struct node {
        char *polname;
        char *devname;
        char *status;
        char *srczone;
        char *dstzone;
        char *srcaddr;
        char *dstaddr;
        char *srcuser;
        char *app;
        char *service;
        char *urlcategory;
        char *action;
        char *vulnerability;


        struct node *next;
            };
        struct node *head;

void insert(char *a, char *b, char *c, char *d, char *e, char *f, char*g, char *h, char *i, char *j, char *k, char *l, char *m){
        struct node *temp;
        temp = (struct node*)malloc(sizeof(struct node));
        temp->polname = a;
        temp->devname = b;
        temp->status = c;
        temp->srczone = d;
        temp->dstzone = e;
        temp->srcaddr = f;
        temp->dstaddr = g;
        temp->srcuser = h;
        temp->app = i;
        temp->service = j;
        temp->urlcategory = k;
        temp->action = l;
        temp->next = head;
        head= temp;
}
/* This is where the error occurs */
void traverse_dom_trees(xmlNode * a_node)
{
    xmlNode *cur_node = NULL;

    for (cur_node = a_node; cur_node; cur_node = cur_node->next)
    {
        if (cur_node->type == XML_ELEMENT_NODE)
        {
              /*  char *a,*b,*c,*d,*e,*f,*g,*h,*i,*j,*k,*l,*m; */
                 if(strcmp((const char *)cur_node->name,(const char *)"policyName") == 0){
                    printf("entered second if");
                    cur_node = cur_node->next;
                    printf("cur_node->next");
                    a = (char *)cur_node->content;
                    printf("value of a is %d", *a);
                    /*strcpy(*a,(const char *)cur_node->content);
                    printf("strcpy");
                    break;*/
               /*     }
             else if(strcmp((const char *)cur_node->name,(const char *)"deviceName") == 0)  {
                     cur_node = cur_node->next;
                    strcpy(*b,(const char *)cur_node->content);
                    break;
                    }
            else if(strcmp((const char *)cur_node->name,(const char *)"status") == 0){
                     cur_node = cur_node->next;
                    strcpy(*c,(const char *)cur_node->content);
                    break;
                    }
            else if(strcmp((const char *)cur_node->name,(const char *)"srcZone") == 0){
                     cur_node = cur_node->next;
                    strcpy(*d,(const char *)cur_node->content);
                    break;
                    }
            else if(strcmp((const char *)cur_node->name,(const char *)"dstZone") == 0){
                     cur_node = cur_node->next;
                    strcpy(*e,(const char *)cur_node->content);
                    break;
                    }
            else if(strcmp((const

 char *)cur_node->name,(const char *)"srcAddr") == 0){
                         cur_node = cur_node->next;
                        strcpy(*f,(const char *)cur_node->content);
                        break;
                        }
                else if(strcmp((const char *)cur_node->name,(const char *)"dstAddr") == 0){
                         cur_node = cur_node->next;
                        strcpy(*g,(const char *)cur_node->content);
                        break;
   }
                else if(strcmp((const char *)cur_node->name,(const char *)"srcUser") == 0){
                         cur_node = cur_node->next;
                         strcpy(*h,(const char *)cur_node->content);
                        break;
                        }
                else if(strcmp((const char *)cur_node->name,(const char *)"application") == 0){
                         cur_node = cur_node->next;
                         strcpy(*i,(const char *)cur_node->content);
                        break;
                        }
                else if(strcmp((const char *)cur_node->name,(const char *)"service") == 0){
                         cur_node = cur_node->next;
                         strcpy(*j,(const char *)cur_node->content);
                        break;
                        }
                else if(strcmp((const char *)cur_node->name,(const char *)"urlCategory") == 0){
                         cur_node = cur_node->next;
                         strcpy(*k,(const char *)cur_node->content);
                        break;
                        }
                else if(strcmp((const char *)cur_node->name,(const char *)"action") == 0){
                         cur_node = cur_node->next;
                         strcpy(*l,(const char *)cur_node->content);
                        break;
                        }
                else if(strcmp((const char *)cur_node->name,(const char *)"vulnerability") == 0){
                         cur_node = cur_node->next;
                         strcpy(*m,(const char *)cur_node->content);
                        break;
                        }*/

          /*insert( a, b, c, d, e, f, g, h, i, j, k, l, m);*/
    }

        traverse_dom_trees(cur_node->children);
    }
}

int main(int argc, char **argv)
{
    xmlDocPtr doc;
    xmlNode *roo_element = NULL;

    if (argc != 2)
    {
        printf("\nInvalid argument\n");
        return(1);
    }

    doc = xmlReadFile(argv[1], NULL, XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NONET);
    if (doc == NULL)
    {
        fprintf(stderr, "Document not parsed successfully.\n");
        return 0;
    }

    roo_element = xmlDocGetRootElement(doc);

    if (roo_element == NULL)
 {
        fprintf(stderr, "empty document\n");
        xmlFreeDoc(doc);
        return 0;
    }

    printf("Root Node is %s\n", roo_element->name);
    traverse_dom_trees(roo_element);

    xmlFreeDoc(doc);       // free document
    xmlCleanupParser();    // Free globals
    return 0;
}

正如您所看到的,我正在尝试使用if/else if语句将相应的值分配给链接列表中的节点,并打印以下内容:

Root Node is policyList
Segmentation fault

我是否应用错误的逻辑来实现我必须做的事情?我应该采用不同的方法吗?

请注意代码,因为它在各个地方似乎很长(我仍在学习阶段)。任何和所有的帮助/建议将不胜感激。在此先感谢:)

编辑1: 我切换到if/else而不是switch/case。此外,之前显示的大多数警告主要是因为错误的分配。我已经评论了大部分bugsy代码,以了解我的代码的哪些部分正在工作以及需要纠正什么。在调试时,我意识到它是无法正常工作的赋值部分,因为我认为我没有使用正确的方法将指针存储器中存在的数据保存到相应的变量/指针变量中。 因为它正在为我打印根节点,而且printf直到第二个if被调用,所以我假设代码的其余部分是正确的,只是指针赋值不能正常工作,因为它应该是

1 个答案:

答案 0 :(得分:0)

content并不包含在XML_ELEMENT_NODE中,而是包含在XML_TEXT_NODE类型的子节点中(请参见Retrieving Element Content),因此我们必须进行更改

                    a = (char *)cur_node->content;

                    a = (char *)cur_node->xmlChildrenNode->content;

                    a = (char *)xmlNodeListGetString(cur_node->doc, cur_node->xmlChildrenNode, 0);

后者返回字符串的副本,可以使用xmlFree()将其释放。