Mini-XML的编译与使用
libmxml (mini-xml) 一个轻量级的xml库,可完成读写。适合系统资源受限的嵌入式设备。
1. 下载
官网网址:https://www.msweet.org/mxml/
测试版本:mxml-3.0.tar.gz
测试环境:Ubuntu 14.04.5 LTS, x64
2. 编译
[email protected]:/opt/xml_lib/mxml-3.0#./configure
[email protected]:/opt/xml_lib/mxml-3.0# make
Compiling mxml-attr.c
Compiling mxml-entity.c
Compiling mxml-file.c
Compiling mxml-get.c
Compiling mxml-index.c
Compiling mxml-node.c
Compiling mxml-search.c
Compiling mxml-set.c
Compiling mxml-private.c
Compiling mxml-string.c
Creating libmxml.so.1.6...
Creating libmxml.a...
a - mxml-attr.o
a - mxml-entity.o
a - mxml-file.o
a - mxml-get.o
a - mxml-index.o
a - mxml-node.o
a - mxml-search.o
a - mxml-set.o
a - mxml-private.o
a - mxml-string.o
Compiling testmxml.c
Linking testmxml...
Testing library...
Stdio file test passed!
String test passed!
File descriptor test passed!
[email protected]:/opt/xml_lib/mxml-3.0# make install
Installing libmxml.so to /usr/local/lib...
Installing libmxml.a to /usr/local/lib...
Installing documentation in /usr/local/share/doc/mxml...
/usr/bin/install: cannot stat ‘doc/mxmldoc.xsd’: No such file or directory
/usr/bin/install: cannot stat ‘COPYING’: No such file or directory
Installing header files in /usr/local/include...
Installing pkgconfig files in /usr/local/lib/pkgconfig...
Installing man pages in /usr/local/share/man...
默认安装路径为 /usr/local/lib,可以在 ./configure 命令行中指定,比如:
./configure --prefix=/opt/xml_lib/x64
如果指定了自定义安装路径,则需要手动指定 LD_LIBRARY_PATH,例如:
export LD_LIBRARY_PATH="/opt/xml_lib/x64/lib"
否则运行出错,如下:
[email protected]:/opt/xml_lib/x64/lib# gcc -o testmxml testmxml.c -lmxml
[email protected]:/opt/xml_lib/x64/lib#
[email protected]:/opt/xml_lib/x64/lib# ./testmxml
./testmxml: error while loading shared libraries: libmxml.so.1:
cannot open shared object file: No such file or directory
[email protected]:/opt/xml_lib/x64/lib# export LD_LIBRARY_PATH="/opt/xml_lib/x64/lib:$LD_LIBRARY_PATH"
[email protected]:/opt/xml_lib/x64/lib# ./testmxml
Usage: testmxml filename.xml [string-output.xml]
configure详细用法可以使用 ./configure --help 来查看
3. 使用
官方指导用法如下图:
但是实测会报错,如下:
[email protected]u:/opt/508/xml_lib/demo# gcc -o testMXML testMXML.c -lmxml
testMXML.c: In function ‘main’:
testMXML.c:27:23: error: dereferencing pointer to incomplete type
printf("[%s}\n",id->child->value.text.string);
^
testMXML.c:31:30: error: dereferencing pointer to incomplete type
printf("[%s]\n",password->child->value.text.string);
^
错误提示表明相关的结构体未定义,跟踪代码后可知,仅包含单个 #include <mxml.h> 是不完全的,需要把三个相关的头文件均关联起来,demo代码如下:
//testMXML.c
//功能:实现XML文件的查询和修改
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
//#include"mxml.h"
#include"mxml-private.h"
const char *whitespace_cb(mxml_node_t *node ,int w)
{
//printf(" curNode:%s; w: %d \n", mxmlGetElement(node), w);
if ( w == MXML_WS_AFTER_OPEN
/*|| w == MXML_WS_BEFORE_CLOSE */
|| w == MXML_WS_AFTER_CLOSE )
return ("\n");
else
return NULL;
}
int main()
{
FILE *fp;
mxml_node_t *tree, *node;
int ret = -1;
fp = fopen("debug_settings.xml", "rb+");
if(fp == NULL){
printf("can not open file!please check it\n");
return -1;
}
tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK);
node = mxmlFindElement(tree, tree, "note",NULL, NULL,MXML_DESCEND);
printf(" year:%s \n",mxmlElementGetAttr(node,"year"));
printf(" date:%s \n",mxmlElementGetAttr(node,"date"));
printf("month:%s \n",mxmlElementGetAttr(node,"month"));
mxml_node_t *id, *password;
id = mxmlFindElement(node, tree, "id",NULL, NULL,MXML_DESCEND);
printf("id[type=%d][value=%s}\n",id->type, id->child->value.text.string);
if(strcmp(id->child->value.text.string, "6666") == 0)
ret = mxmlSetText(id, 0, "5555");
else
ret = mxmlSetText(id, 0, "6666");
printf("mxmlSetText() ret: %d;\n", ret);
printf("id[type=%d][value=%s}\n",id->type, id->child->value.text.string);
password = mxmlFindElement(node, tree, "password",NULL, NULL,MXML_DESCEND);
printf("password[type=%d][value=%s}\n",password->type, password->child->value.text.string);
id = mxmlFindElement(node, tree, "id",NULL, NULL,MXML_DESCEND);
printf("id[type=%d][value=%s}\n",id->type, id->child->value.text.string);
fseek(fp, 0, SEEK_SET);
ret = mxmlSaveFile ( tree, fp, whitespace_cb );
printf("mxmlSaveFile() ret: %d;\n", ret);
if(ret)
perror("mxmlSaveFile err:");
fclose(fp);
fp = NULL;
mxmlDelete(tree);
return 0 ;
}
文件结构
[email protected]:/opt/xml_lib/demo# ls -l
total 52
-rw-r--r-- 1 root root 1840 May 5 19:00 config.h
-rwxr--r-- 1 nobody nogroup 138 May 5 23:33 debug_settings.xml
-rw-r--r-- 1 root root 10334 May 5 18:47 mxml.h
-rw-r--r-- 1 root root 2666 May 5 18:59 mxml-private.h
-rwxr--r-- 1 nobody nogroup 1834 May 5 23:33 testMXML.c
编译命令
[email protected]:/opt/xml_lib/demo# gcc -Wall -g -O3 -o testMXML testMXML.c -lmxml
[email protected]:/opt/xml_lib/demo# file testMXML
testMXML: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs),
for GNU/Linux 2.6.24, BuildID[sha1]=7bbe65f23ec4bf400ae634208f3723ad6e9bc726, not stripped
测试文件
<?xml version="1.0" encoding="gb2312" ?>
<note year="55" date="33" month="22">
<id>6666</id>
<password>FE-D0-18-00</password>
</note>
4. 优点
- 轻量级 —— 代码量小
- 使用简单 —— 简单使用几个函数即可
5. 缺点
- 默认XML无格式,无可读性 —— 需要自己实现格式化函数 whitespace_cb() ,默认输出XML没有换行分割,如下图:
若有比较好的格式化函数 whitespace_cb(), 麻烦在评论中发一下。
6. 参考
- 使用mini-XML库实现xml文件的创建以及解析 https://blog.****.net/alangdangjia/article/details/8874572
- Mini-XML从入门到精通系列–源码获取及安装 https://blog.****.net/bbzhaohui/article/details/71512599
- mini-XML 中文文档 https://blog.****.net/bluesonic/article/details/3887143
- XML压缩、格式化工具 http://www.bejson.com/otherformat/xml/
以上