0

私は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;
    }

この問題を解決するのを手伝ってもらえますか?

4

2 に答える 2

2

試す:

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);
    }

}
于 2012-06-27T14:28:52.953 に答える
1

問題はここにあります:

// 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;

isのwhile 場合に終了し、次のステートメントを逆参照します。したがって、のクラッシュ。 たぶん、あなたはたぶんこれらの行で単一のループで比較を試みることができます: curNULLcur = cur->xmlChildrenNode;cur->xmlChildrenNode

while (cur != NULL) {
    if ((!xmlStrcmp(cur->name, (const xmlChar *) "system-modules"))) {
        parseSystemModules(doc, cur);
    }
    else if ((!xmlStrcmp(cur->name, (const xmlChar *) "system-configuration"))) {
        parseSystemConfiguration(doc, cur);
    }
    cur = cur->next;
}

お役に立てれば!

于 2012-06-27T14:35:49.907 に答える