c - 尝试解析 xml 文件时出现段错误

标签 c xml libxml2

我是 C 编程新手。我想创建可以使用 libxml2 读取 XML 文件的 C 程序。 我测试了这段代码:

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

// Declare functions
void parseSystemProperties(char *xmlFileName);
void parseSystemModules(xmlDocPtr doc, xmlNodePtr cur);
void parseSystemConfiguration(xmlDocPtr doc, xmlNodePtr cur);
void parseProfiles(xmlDocPtr doc, xmlNodePtr cur);
void parseMonitoringPort(xmlDocPtr doc, xmlNodePtr cur);
void parseWebServicePort(xmlDocPtr doc, xmlNodePtr cur);
void parseBindingInterfaces(xmlDocPtr doc, xmlNodePtr cur);
void parseExtensions(xmlDocPtr doc, xmlNodePtr cur);

int main(int argc, char **argv) {
    char *xmlFileName;

    if (argc <= 1) {
        printf("Usage: %s inputfile.xml\n", argv[0]);
        return (0);
    }

    // Get the file name from the argv[1]
    xmlFileName = argv[1];

    // Custom function to parse XML file
    parseSystemProperties(xmlFileName);

    return (1);
}

// Parsing the XML file and Reading the Element Nodes

void parseSystemProperties(char *xmlFileName) {
    xmlDocPtr doc; // pointer to parse xml Document
    xmlNodePtr cur; // node pointer. It interacts with individual node

    // Parse XML file
    doc = xmlParseFile(xmlFileName);

    // Check to see that the document was successfully parsed.
    if (doc == NULL) {
        fprintf(stderr, "Error!. Document is not parsed successfully. \n");
        return;
    }

    // Retrieve the document's root element - system-properties
    cur = xmlDocGetRootElement(doc);

    // Check to make sure the document actually contains something
    if (cur == NULL) {
        fprintf(stderr, "Document is Empty\n");
        xmlFreeDoc(doc);
        return;
    }

    /* We need to make sure the document is the right type.
     * "system-properties" is the root type of the documents used in user Config XML file
     */
    if (xmlStrcmp(cur->name, (const xmlChar *) "system-properties")) {
        fprintf(stderr, "Cannot find system-properties");
        xmlFreeDoc(doc);
        return;
    }

    /* Get the first child node of cur.
     * At this point, cur points at the document root,
     * which is the element "root"
     */

    cur = cur->xmlChildrenNode;

    // This loop iterates through the elements that are children of "root"
    while (cur != NULL) {
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "system-modules"))) {
            parseSystemModules(doc, cur);
        }
        cur = cur->next;
    }


    cur = cur->xmlChildrenNode;

    // This loop iterates through the elements that are children of "root"
    while (cur != NULL) {
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "system-configuration"))) {
            parseSystemConfiguration(doc, cur);
        }
        cur = cur->next;
    }

    /* Save XML document to the Disk
     * Otherwise, you changes will not be reflected to the file.
     * Currently it's only in the memory
     */
    // xmlSaveFormatFile (xmlFileName, doc, 1);

    /* free the document */
    xmlFreeDoc(doc);

    /*
     * Free the global variables that may
     * have been allocated by the parser.
     */
    xmlCleanupParser();

    return;

} // end of function

// Get Modules part
// -------------------------------------------

void parseSystemModules(xmlDocPtr doc, xmlNodePtr cur) {
    xmlChar *key;
    xmlAttrPtr attr;

    // Get the sub Element Node of system-configuration node
    cur = cur->xmlChildrenNode;

    // This loop iterates through the elements that are children of system-configuration
    while (cur != NULL) {
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "extensions"))) {
            parseExtensions(doc, cur);
        }
        cur = cur->next;
    }

    return;

} // end of function()

void parseExtensions(xmlDocPtr doc, xmlNodePtr cur) {
    xmlChar *key;
    xmlAttrPtr attr;

    // Get the sub Element Node of Profiles node
    cur = cur->xmlChildrenNode;

    // This loop iterates through the elements that are children of Profiles
    while (cur != NULL) {
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "extension"))) {
            key = xmlGetProp(cur, (const xmlChar*) "module");
            fprintf(stderr, "module: %s\n", key);
            xmlFree(key);
        }
        cur = cur->next;
    }

    return;

} // end of function()



// Get Configuration part
// -------------------------------------------

void parseSystemConfiguration(xmlDocPtr doc, xmlNodePtr cur) {
    xmlChar *key;
    xmlAttrPtr attr;

    // Get the sub Element Node of system-configuration node
    cur = cur->xmlChildrenNode;

    // This loop iterates through the elements that are children of system-configuration
    while (cur != NULL) {
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "profiles"))) {
            parseProfiles(doc, cur);
        }
        cur = cur->next;
    }

    return;

} // end of function()

void parseProfiles(xmlDocPtr doc, xmlNodePtr cur) {
    xmlChar *key;
    xmlAttrPtr attr;

    // Get the sub Element Node of Profiles node
    cur = cur->xmlChildrenNode;

    // This loop iterates through the elements that are children of Profiles
    while (cur != NULL) {
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "profile"))) {
            // Get monitoring-port
            parseMonitoringPort(doc, cur);
            // Get web-service-port
            parseWebServicePort(doc, cur);
            parseBindingInterfaces(doc, cur);
        }
        cur = cur->next;
    }

    return;

} // end of function()


// Monitoring Port

void parseMonitoringPort(xmlDocPtr doc, xmlNodePtr cur) {
    xmlChar *key;
    xmlAttrPtr attr;

    // Get the sub Element Node of Profile node
    cur = cur->xmlChildrenNode;

    // This loop iterates through the elements that are children of Profile
    while (cur != NULL) {
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "monitoring-port"))) {
            key = xmlGetProp(cur, (const xmlChar*) "port");
            fprintf(stderr, "monitoring-port: %s\n", key);
            xmlFree(key);
        }
        cur = cur->next;
    }

    return;

} // end of function()


// web service port

void parseWebServicePort(xmlDocPtr doc, xmlNodePtr cur) {
    xmlChar *key;
    xmlAttrPtr attr;

    // Get the sub Element Node of Profile node
    cur = cur->xmlChildrenNode;

    // This loop iterates through the elements that are children of "root"
    while (cur != NULL) {
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "web-service-port"))) {
            //parseMonitoringPort (doc, cur);
            key = xmlGetProp(cur, (const xmlChar*) "port");
            fprintf(stderr, "web-service-port: %s\n", key);
            xmlFree(key);
        }
        cur = cur->next;
    }

    return;

} // end of function()


// binding interface

void parseBindingInterfaces(xmlDocPtr doc, xmlNodePtr cur) {
    xmlChar *key;
    xmlAttrPtr attr;

    // Get the sub Element Node of Profile node
    cur = cur->xmlChildrenNode;

    // This loop iterates through the elements that are children of "root"
    while (cur != NULL) {
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "socket-binding"))) {
            //parseMonitoringPort (doc, cur);
            key = xmlGetProp(cur, (const xmlChar*) "interface");
            fprintf(stderr, "interface: %s\n", key);
            xmlFree(key);
        }
        cur = cur->next;
    }

    return;

} // end of function()

这是我要读取的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<system-properties version="1.0">
    <system-modules>
        <extensions>
            <extension module="NetworkModule"/>
            <extension module="MonitoringModule"/>
            <extension module="OracleModule"/>
            <extension module="DataFilterModule"/>          
        </extensions>   
    </system-modules>
    <system-configuration>
        <profiles>
            <profile name="default">
                <monitoring-port port="6051"/>
                <web-service-port port="7050"/>
                <socket-binding interface="management" ipaddress="192.168.1.101" port="6050"/>
                <socket-binding interface="monitoring" ipaddress="192.168.1.106" port="7050"/>
                <network-pool threads="40"/>                    
            </profile>
        </profiles>
    </system-configuration>
</system-properties>

不幸的是,当我运行示例时出现此错误:

[rcbandit@Laptop Ctest]$ ./test xmlfile.xml
module: NetworkModule
module: MonitoringModule
module: OracleModule
module: DataFilterModule
Segmentation fault (core dumped)
[user@Laptop Ctest]$ 

当我删除这一行时,代码可以工作:

cur = cur->xmlChildrenNode;

    // This loop iterates through the elements that are children of "root"
    while (cur != NULL) {
        if ((!xmlStrcmp(cur->name, (const xmlChar *) "system-modules"))) {
            parseSystemModules(doc, cur);
        }
        cur = cur->next;
    }

你能帮我解决这个问题吗?

最佳答案

尝试:

cur = (cur) ? cur->xmlChildrenNode : NULL;

您还可以将其添加到循环逻辑中:

for(cur = (cur) ? cur->xmlChildrenNode: NULL; cur; cur = cur->next) {
// This loop iterates through the elements that are children of "root"  
    if ((!xmlStrcmp(cur->name, (const xmlChar *) "system-modules"))) {
        parseSystemModules(doc, cur);
    }

}

关于c - 尝试解析 xml 文件时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11228304/

相关文章:

java - 将 libxml 添加到 Red Hat 中的 Eclipse 项目

与指针数组中的引用项混淆

C 奇数 if 语句

java - 如何在每个 Activity 中显示滑动菜单栏?

iphone - 使用 GDataXMLDocument 解析 xml 属性

c# - 如何通过 Xml 属性重命名类名?

android - C套接字()问题

c - 允许 NULL arg 进行 sscanf?

c - 使用 libxml2 读取 XML

xml - 使用 XML::LibXML:如何创建 namespace 和子元素并使它们协同工作?