配置文件示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<Day>7</Day>
<partitions>
<partition>
<ip>192.168.2.213</ip>
<port>5730</port>
</partition>
<partition>
<ip>192.168.2.230</ip>
<port>9003</port>
</partition>
</partitions>
</config>
首先定义存储信息的结构体:
typedef struct _partition {
char ip[STRING_SIZE_MAX];
int port;
} partition_t;
typedef struct _config {
int day;
int partitions_count;
partition_t p[MAX];
} config_t;
然后就可以用libxml中的函数封装接口了,主要引用的头文件有:
#include "xmlwriter.h"
#include "xmlreader.h"
#include "parser.h"
接口封装:
int load_config(config_t *c, const char *file) {
int ret = 0;
xmlDocPtr doc;
xmlNodePtr cur;
xmlChar *key = NULL;
doc = xmlParseFile(file);
if(doc == NULL) {
return -1;
}
cur = xmlDocGetRootElement(doc);//求根节点
if(cur == NULL) {
gerr("root element get fail.");
xmlFreeDoc(doc);
return -1;
}
//判断根节点是否为config
if(xmlStrcmp(cur->name, (const xmlChar *)("config")) != 0) {
gerr("root element error:%s", (const char *)(cur->name));
xmlFreeDoc(doc);
return -1;
}
//进到孩子节点
cur = cur->xmlChildrenNode;
while(cur != NULL) {
if(xmlStrcmp(cur->name, (const xmlChar *)("Day")) == 0) {
key = xml_node_strval(doc, cur);
if(key != NULL) {
c->day = atoi((char *)key);
xmlFree(key);
gdebug("%s=%d", (const char *)cur->name, c->day);
}
} else if(xmlStrcmp(cur->name, (const xmlChar *)("partitions")) == 0) {
ret = load_partitions(c, doc, cur);
if(ret != 0) {
gdebug("parse device list fail.");
return -1;
}
}
//遍历兄弟节点
cur = cur->next;
}
xmlFreeDoc(doc);
return 0;
}
static int load_partition(partition_t *pt, xmlDocPtr doc, xmlNodePtr cur) {
int ret=0;
xmlChar *key;
cur = cur->xmlChildrenNode;
while(cur != NULL) {
if(xmlStrcmp(cur->name, (const xmlChar *)("ip")) == 0) {
key = xml_node_strval(doc, cur);
if(key != NULL) {
strncpy(pt->ip, (const char *)key, sizeof(pt->ip));
xmlFree(key);
gdebug("%s=%s", (const char *)cur->name, pt->ip);
}
} else if(xmlStrcmp(cur->name, (const xmlChar *)("port")) == 0) {
key = xml_node_strval(doc, cur);
if(key != NULL) {
pt->port = atoi((char *)key);
xmlFree(key);
gdebug("%s=%d", (const char *)cur->name, pt->port);
}
}
cur = cur->next;
}
return 0;
}
static int load_partitions(config_t *c, xmlDocPtr doc, xmlNodePtr cur) {
int ret = 0;
int i = 0;
cur = cur->xmlChildrenNode;
while(cur != NULL) {
if(xmlStrcmp(cur->name, (const xmlChar *)("partition")) == 0) {
ret = load_partition(&c->p[i++], doc, cur);
if(ret != 0) {
gerr("partition load failure.");
return -1;
}
gdebug("partition load done.");
}
cur = cur->next;
}
return 0;
}