私は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;
}
この問題を解決するのを手伝ってもらえますか?