c - 解析XML文件并写入链表

标签 c linked-list xml-parsing

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

文件.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>

文件.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。此外,之前显示的大部分警告主要是因为分配错误。我已经对大部分错误代码进行了注释,以了解我的代码的哪些部分可以正常工作以及需要更正哪些部分。在调试时,我意识到赋值部分不起作用,因为我认为我没有使用正确的方法将指针内存中的数据保存到相应的变量/指针变量。 因为它正在为我打印根节点以及 printf 直到第二个 if 被调用,所以我假设其余代码是正确的,只是指针分配没有像预期的那样工作到。

最佳答案

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() 释放它。

关于c - 解析XML文件并写入链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47605539/

相关文章:

C++ 链表遗留代码到 STL——动态分配链表大小

java - MapReduce程序中的XMLParser失败,并显示以下消息:实体名称必须立即在实体引用中的 '&'之后。

xml 中的 Android 谷歌地图 fragment 。我得到 "Unexpected namespace prefix"

c - Syslog 目录不存在

添加到链接列表时出现 java.lang.stackoverflowerror

c - 如何事先确定无符号计算是否可能溢出?

C - 将数组传递给链表的节点

xml - 在 R XML 包中,xmlParse 和 xmlTreeParse 有什么区别?

c - 如何在 C 中通过引用将数组指针传递给函数?

java - Android: native 进程在一段时间后引发 ReferenceTable 溢出 (android-ndk)