linux c 使用libxml2 读写xml格式配置文件

linux c使用libxml2读取配置文件 


Libxml2是个C语言的XML程式库,能简单方便的提供对XML文件的各种操作,并且支持XPATH查询,及部分的支持XSLT转换等功能。完全版的库是开源的,并且带有例子程式和说明文件。


libxml2的安装
 


yum install libxml2 libxml2-devel -y
或者
#sudo apt-get install libxml2 libxml2-dev
或者
下载libxml2-2.6.20.tar.gz版本的源码包。
wget http://ftp.gnome.org/pub/GNOME/sources/libxml2/2.6/libxml2-2.6.0.tar.bz2
1、解压:$tar zxvf libxml2-2.6.20.tar.gz
2、进入解压后的安装目录:$cd libxml2-2.6.20
3、安装三部曲:1)$./configure
              2)$make
              3)$make install
安装完毕。


libxml2安装中出现的错误:
cannot remove `libtoolT': No such file or directory
解决方法:
修改configure文件
$ vim configure
删除这一行: $RM "$cfgfile" 
重新再运行 $ ./configure

 

创建xml

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlmemory.h>

#define PHONE_BOOK_FILE "phone_book.xml"
#define ID_STR_LEN 16
#define NAME_STR_LEN 32
#define TEL_STR_LEN 16
#define ADDR_STR_LEN 128

//电话通讯录结构体
typedef struct phone_t {
int id; //编号
char name[NAME_STR_LEN]; //姓名
char tel[TEL_STR_LEN]; //电话
char address[ADDR_STR_LEN]; //地址
}phone;

//设置通讯录项
static void set_phone_item(phone *phone_item)
{
assert(phone_item);

phone_item->id = 10;
snprintf(phone_item->name, NAME_STR_LEN, "%s", "Anker");
snprintf(phone_item->tel, TEL_STR_LEN, "%s", "13223246599");
snprintf(phone_item->address, ADDR_STR_LEN, "%s", "Shenzheng");
}

//创建phone节点
static xmlNodePtr create_phone_node(const phone *phone_item)
{
assert(phone_item);

char id[ID_STR_LEN] = {0};
xmlNodePtr phone_node = NULL;

phone_node = xmlNewNode(NULL, BAD_CAST"phone");
if (phone_node == NULL) {
fprintf(stderr, "Failed to create new node.\n");
return NULL;
}
//设置属性
snprintf(id, ID_STR_LEN, "%d", phone_item->id);
xmlNewProp(phone_node, BAD_CAST"id", (xmlChar*)id);

xmlNewChild(phone_node, NULL, BAD_CAST"name", (xmlChar *)phone_item->name);
xmlNewChild(phone_node, NULL, BAD_CAST"tel", (xmlChar *)phone_item->tel);
xmlNewChild(phone_node, NULL, BAD_CAST"address", (xmlChar *)phone_item->address);

return phone_node;
}

//向根节点中添加一个phone节点
static int add_phone_node_to_root(xmlNodePtr root_node)
{
xmlNodePtr phone_node = NULL;
phone *phone_item = NULL;

//创建一个新的phone
phone_item = (phone *)malloc(sizeof(phone));
if (phone_item == NULL) {
fprintf(stderr, "Failed to malloc memory.\n");
return -1;
}
set_phone_item(phone_item);

//创建一个phone节点
phone_node = create_phone_node(phone_item);
if (phone_node == NULL) {
fprintf(stderr, "Failed to create phone node.\n");
goto FAILED;
}
//根节点添加一个子节点
xmlAddChild(root_node, phone_node);
free(phone_item);

return 0;
FAILED:
if (phone_item){
free(phone_item);
}
return -1;
}

//创建phone_books
static int create_phone_books(const char *phone_book_file)
{
assert(phone_book_file);

xmlDocPtr doc = NULL;
xmlNodePtr root_node = NULL;

//创建一个xml 文档
doc = xmlNewDoc(BAD_CAST"1.0");
if (doc == NULL) {
fprintf(stderr, "Failed to new doc.\n");
return -1;
}

//创建根节点
root_node = xmlNewNode(NULL, BAD_CAST"phone_books");
if (root_node == NULL) {
fprintf(stderr, "Failed to new root node.\n");
goto FAILED;
}
//将根节点添加到文档中
xmlDocSetRootElement(doc, root_node);

if (add_phone_node_to_root(root_node) != 0) {
fprintf(stderr, "Failed to add a new phone node.\n");
goto FAILED;
}
//将文档保存到文件中,按照utf-8编码格式保存
xmlSaveFormatFileEnc(phone_book_file, doc, "UTF-8", 1);
//xmlSaveFile("test.xml", doc);
xmlFreeDoc(doc);

return 0;
FAILED:
if (doc) {
xmlFreeDoc(doc);
}

return -1;
}

static int add_phone_node(const char *phone_book_file)
{
assert(phone_book_file);

xmlDocPtr doc = NULL;
xmlNodePtr root_node = NULL;
xmlNodePtr phone_node = NULL;
phone *phone_item = NULL;

doc = xmlParseFile(phone_book_file);
if (doc == NULL) {
fprintf(stderr, "Failed to parser xml file:%s\n", phone_book_file);
return -1;
}

root_node = xmlDocGetRootElement(doc);
if (root_node == NULL) {
fprintf(stderr, "Failed to get root node.\n");
goto FAILED;
}

if (add_phone_node_to_root(root_node) != 0) {
fprintf(stderr, "Failed to add a new phone node.\n");
goto FAILED;
}
//将文档保存到文件中,按照utf-8编码格式保存
xmlSaveFormatFileEnc(phone_book_file, doc, "UTF-8", 1);
xmlFreeDoc(doc);

return 0;
FAILED:
if (doc) {
xmlFreeDoc(doc);
}

return -1;
}

int main(int argc, char *argv[])
{
char *phone_book_file = PHONE_BOOK_FILE;

if (argc == 2) {
phone_book_file = argv[1];
}

if (access(phone_book_file, F_OK) == 0) {
//文件存在,添加一个新的phone节点
add_phone_node(phone_book_file);
}
else {
//文件不存在,创建一个信息的phone book
create_phone_books(phone_book_file);
}

return 0;
}

编译命令如下:
gcc -g create_phone_book.c -o create_phone_book -I /usr/include/libxml2/ -lxml2

解析XML

#include <stdio.h>
#include <assert.h>

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

#define DEFAULT_XML_FILE "phone_book.xml"

//解析每一个phone,提取出name、tel、address
static int parse_phone(xmlDocPtr doc, xmlNodePtr cur)
{
assert(doc || cur);
xmlChar *key;

cur = cur->xmlChildrenNode;
while (cur != NULL) {
//获取name
if ((!xmlStrcmp(cur->name, (const xmlChar *)"name"))) {
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
printf("name: %s\t", key);
xmlFree(key);
}
//获取tel
if ((!xmlStrcmp(cur->name, (const xmlChar *)"tel"))) {
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
printf("tel: %s\t", key);
xmlFree(key);
}
//获取address
if ((!xmlStrcmp(cur->name, (const xmlChar *)"address"))) {
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
printf("address: %s\n", key);
xmlFree(key);
}
cur = cur->next;
}
return 0;
}

static int parse_phone_book(const char *file_name)
{
assert(file_name);

xmlDocPtr doc; //xml整个文档的树形结构
xmlNodePtr cur; //xml节点
xmlChar *id; //phone id

//获取树形结构
doc = xmlParseFile(file_name);
if (doc == NULL) {
fprintf(stderr, "Failed to parse xml file:%s\n", file_name);
goto FAILED;
}

//获取根节点
cur = xmlDocGetRootElement(doc);
if (cur == NULL) {
fprintf(stderr, "Root is empty.\n");
goto FAILED;
}

if ((xmlStrcmp(cur->name, (const xmlChar *)"phone_books"))) {
fprintf(stderr, "The root is not phone_books.\n");
goto FAILED;
}

//遍历处理根节点的每一个子节点
cur = cur->xmlChildrenNode;
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)"phone"))) {
id = xmlGetProp(cur, "id");
printf("id:%s\t",id);
parse_phone(doc, cur);
}
cur = cur->next;
}
xmlFreeDoc(doc);
return 0;
FAILED:
if (doc) {
xmlFreeDoc(doc);
}
return -1;
}

int main(int argc, char*argv[])
{
char *xml_file = DEFAULT_XML_FILE;

if (argc == 2) {
xml_file = argv[1];
}

if (parse_phone_book(xml_file) != 0) {
fprintf(stderr, "Failed to parse phone book.\n");
return -1;
}

return 0;
}

gcc -g xml_phone_book_read.c -o phone_book -I /usr/include/libxml2/ -lxml2

 

猜你喜欢

转载自blog.csdn.net/elikang/article/details/85326770
今日推荐