老程序员分享:libxml2的安装及使用【总结】

简介: 老程序员分享:libxml2的安装及使用【总结】

1、前言


  xml广泛应用于网络数据交换,配置文件、Web服务等等。近段时间项目中做一些配置文件,原来是用ini,现在改用xml。xml相对来说可视性更为直观,很容易看出数据之间的层次关系。关于xml的详细介绍可以参考本文重点介绍解析xml的libxml2库的安装及使用,举例说明创建和解析xml的过程。


2、libxml2的安装


  关于libxml2的介绍请参考官方网址下载最新的libxml2库


具体安装步骤:


1、解压:$tar zxvf libxml2-2.9.1.tar.gz


2、进入解压后的安装目录:$cd libxml2-2.9.1


3、安装三部曲:


     1)$./configure


2)$make


3)$make install


安装完毕。


注意:libxml2默认安装到/usr/local/include/libxml2目录下


3、xml文档结构


  xml按照树形结构进行存储,节点分为元素和文本,必须有根节点。如下的xml文件:


<?xml version="1.0" encoding="UTF-8"?>


[/span>phone_books

[/span>phone id="1"

[/span>name

[/span>tel

[/span>address


[/span>phone id="2"

[/span>name

[/span>tel

[/span>address


[/span>phone id="3"

[/span>name

[/span>tel

[/span>address



xml结构图如下所示:


4、测试例子


关于libxml2的提供的接口,可以参考http://blog.csdn.net/shanzhizi/article/details/7726679。libxml2常用的接口如下:


  内部字符类型:xmlChar,定义为:typedef unsigned char xmlChar,用无符号型的char方便表示utf-8编码。libxml2提供了一个宏进行转换,#define BAD_CAST (xmlChar )。


文档类型xmlDoc,指针类型xmlDocPtr。xmlDoc是个struct,保存了一个xml的相关信息,例如文件名、文件类型、子节点等等;xmlDocPtr等于xmlDoc


  xmlNewDoc函数创建一个新的文件指针。


  xmlParseFile函数以默认方式读入一个UTF-8格式的文件,并返回文件指针。


  xmlReadFile函数读入一个带有某种编码的xml文件,并返回文件指针;细节见libxml2参考手册。


  xmlFreeDoc释放文件指针。特别注意,当你调用xmlFreeDoc时,该文件所有包含的节点内存都被释放。 


  xmlFreeNodeList来释放动态分配的节点内存,除非你把该节点从文件中移除了。


xmlSaveFile将文件以默认方式存入一个文件。


xmlSaveFormatFileEnc可将文件以某种编码/格式存入一个文件中。


  节点类型xmlNode、指针xmlNodePtr


  节点应该是xml中最重要的元素了,xmlNode代表了xml文件中的一个节点,实现为一个struct,内容非常丰富:tree.h


  xmlDocSetRootElement函数能将一个节点设置为某个文件的根节点


xmlNewNode函数创建一个节点指针root_node


(1)创建xml文件


测试程序如下所示:


1 /**


2 练习libxml库,创建通讯录xml文档,新增一个通讯录,


3 如果xml文件存在,则添加一个新节点


4 如果xml文件不存在,则新建一个xml文件


5


6 @author: Anker @date: 2014/02/09


7 */


8


9 #include


10 #include [span style="color: rgba(0, 0, 255, 1)">string.h>


11 #include


12 #include


13


14 #include


15 #include


16 #include


17


18 #define PHONE_BOOK_FILE "phone_book.xml"


19 #define ID_STR_LEN 16


20 #define NAME_STR_LEN 32


21 #define TEL_STR_LEN 16


22 #define ADDR_STR_LEN 128


23


25 typedef struct phone_t {


26 int id; //编号


27 char name【NAME_STR_LEN】; //姓名


29 char address【ADDR_STR_LEN】; //地址


30 }phone;


31


32 //设置通讯录项


33 static void set_phone_item(phone phone_item)


34 {


35 assert(phone_item);


36


37 phone_item->id = 10;


38 snprintf(phone_item->name, NAME_STR_LEN, "%s", "Anker");


39 snprintf(phone_item->tel, TEL_STR_LEN, "%s", "13223246599");


40 snprintf(phone_item->address, ADDR_STR_LEN, "%s", "Shenzheng");


41 }


42


43 //创建phone节点


44 static xmlNodePtr create_phone_node(const phone phone_item)


45 {


46 assert(phone_item);


47


48 char id【ID_STR_LEN】 = {0};


49 xmlNodePtr phone_node = NULL;


50


51 phone_node = xmlNewNode(NULL, BAD_CAST"phone");


52 if (phone_node == NULL) {


53 fprintf(stderr, "Failed to create new node.\n");


54 return NULL;


55 }


56 //设置属性


57 snprintf(id, ID_STR_LEN, "%d", phone_item->id);


58 xmlNewProp(phone_node, BAD_CAST"id", (xmlChar)id);


59


60 xmlNewChild(phone_node, NULL, BAD_CAST"name", (xmlChar )phone_item->name);


61 xmlNewChild(phone_node, NULL, BAD_CAST"tel", (xmlChar )phone_item->tel);


62 xmlNewChild(phone_node, NULL, BAD_CAST"address", (xmlChar )phone_item->address);


63


64 return phone_node;


65 }


66


67 //向根节点中添加一个phone节点


68 static int add_phone_node_to_root(xmlNodePtr root_node)


69 {


70 xmlNodePtr phone_node = NULL;


71 phone phone_item = NULL;


72


73 //创建一个新的phone


74 phone_item = (phone )malloc(sizeof(phone));


75 if (phone_item == NULL) {


76 fprintf(stderr, "Failed to malloc memory.\n");


77 return -1;


78 }


79 set_phone_item(phone_item);


80


81 //创建一个phone节点


82 phone_node = create_phone_node(phone_item);


83 if (phone_node == NULL) {


84 fprintf(stderr, "Failed to create phone node.\n");


85 goto FAILED;


86 }


87 //根节点添加一个子节点


88 xmlAddChild(root_node, phone_node);


89 free(phone_item);


90


91 return 0;


92 FAILED:


93 if (phone_item){


94 free(phone_item);


95 }


96 return -1;


97 }


98


99 //创建phone_books


100 static int create_phone_books(const char phone_book_file)


101 {


102 assert(phone_book_file);


103


104 xmlDocPtr doc = NULL;


105 xmlNodePtr root_node = NULL;


106


107 //创建一个xml 文档


108 doc = xmlNewDoc(BAD_CAST"1.0");


109 if (doc == NULL) {


110 fprintf(stderr, "Failed to new doc.\n");


111 return -1;


112 }


113


114 //创建根节点


115 root_node = xmlNewNode(NULL, BAD_CAST"phone_books");


116 if (root_node == NULL) {


117 fprintf(stderr, "Failed to new root node.\n");


118 goto //代码效果参考:http://www.jhylw.com.cn/061132909.html

FAILED;

119 }


120 //将根节点添加到文档中


121 xmlDocSetRootElement(doc, root_node);


122


123 if (add_phone_node_to_root(root_node) != 0) {


124 fprintf(stderr, "Failed to add a new phone node.\n");


125 goto FAILED;


126 }


127 //将文档保存到文件中,按照utf-8编码格式保存


128 xmlSaveFormatFileEnc(phone_book_file, doc, "UTF-8", 1);


129 //xmlSaveFile("test.xml", doc);


130 xmlFreeDoc(doc);


131


132 return 0;


133 FAILED:


134 if (doc) {


135 xmlFreeDoc(doc);


136 }


137


138 return -1;


139 }


140


141 static int add_phone_node(const char phone_book_file)


14//代码效果参考:http://www.jhylw.com.cn/130337105.html

2 {

143 assert(phone_book_file);


144


145 xmlDocPtr doc = NULL;


146 xmlNodePtr root_node = NULL;


147 xmlNodePtr phone_node = NULL;


148 phone *phone_item = NULL;


149


150 doc = xmlParseFile(phone_book_file);


151 if (doc == NULL) {


152 fprintf(stderr, "Failed to parser xml file:%s\n", phone_book_file);


153 return -1;


154 }


155


156 root_node = xmlDocGetRootElement(doc);


157 if (root_node == NULL) {


158 fprintf(stderr, "Failed to get root node.\n");


159 goto FAILED;


160 }


<span style="color: rgba(0, 128, 128, 1)

相关文章
|
7月前
|
Ubuntu 安全
Ubuntu中遇到"无法创建临时文件"/tmp/..."在普通或root用户运行apt-get update时的错误解决办法
这些步骤当然不能涵盖所有可能出现问题的场合,但是能覆盖大多数常见的情景。希望这些信息能帮到你解决"无法创建临时文件"/tmp/..."这样的问题。不过,请记住,因为修改系统文件和目录的权限,清理临时文件,或者运行磁盘检查,都可能对系统造成影响,所以执行这些操作前要先确认这是安全的,必要时最好先做好数据备份。
441 10
|
Linux 数据安全/隐私保护 Perl
CentOS7中升级OpenSSL详细教程
这篇文章提供了在CentOS 7系统中升级OpenSSL到3.2版本的详细步骤,包括备份现有配置、安装依赖、下载安装新版本以及验证安装结果。
3110 3
|
Linux C++
Linux C/C++之IO多路复用(poll,epoll)
这篇文章详细介绍了Linux下C/C++编程中IO多路复用的两种机制:poll和epoll,包括它们的比较、编程模型、函数原型以及如何使用这些机制实现服务器端和客户端之间的多个连接。
449 0
Linux C/C++之IO多路复用(poll,epoll)
|
C语言
C语言结构体赋值的四种方式
本文总结了C语言结构体的四种赋值方式,并通过示例代码和编译运行结果展示了每种方式的特点和效果。
1507 6
|
Rust 监控 网络协议
EtherCAT主站IgH解析(一)--主站初始化、状态机与EtherCAT报文
本文介绍了IgH EtherCAT Master整体运行原理
2214 0
EtherCAT主站IgH解析(一)--主站初始化、状态机与EtherCAT报文
|
SQL 数据可视化 关系型数据库
SQLite3使用笔记(1)——查询
SQLite3使用笔记(1)——查询
775 0
|
XML API C语言
深入对比XML处理库:Mini-XML、TinyXML-2与libxml2
深入对比XML处理库:Mini-XML、TinyXML-2与libxml2
1007 2
|
C语言 Linux
linux系统的glibc是什么?为什么很重要?
【6月更文挑战第3天】linux系统的glibc是什么?为什么很重要?
1436 2
|
编译器 C语言 C++
CMake基础(7)编译标志
CMake基础(7)编译标志
984 0
|
数据库连接 API 数据库
SQLite3 数据库 C语言API 打开函数sqlite3_open 详解
SQLite3 数据库 C语言API 打开函数sqlite3_open 详解
764 0

热门文章

最新文章