C语言中使用libxml2安装并创建解析XML文件

C语言中使用libxml2安装并创建解析XML文件

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文件:

[/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 }

« 家庭自制美味肉酱的详细做法步骤分享与技巧解析 4399游戏玩不了怎么办?这几个方法帮你快速解决! »

相关阅读

安卓音乐编辑软件排行榜
365体育直播下载安装

安卓音乐编辑软件排行榜

⌚ 08-02 👁️ 9242
产品不差口碑差,联想到底哪错了?
365体育直播下载安装

产品不差口碑差,联想到底哪错了?

⌚ 07-25 👁️ 2426
电动三轮电池充电方法与注意事项详解
365提款成功但是不到账

电动三轮电池充电方法与注意事项详解

⌚ 11-26 👁️ 721