文档章节

linux下使用libxml2库读写XML文件

北风其凉
 北风其凉
发布于 2014/09/03 14:06
字数 1000
阅读 413
收藏 1

一、安装libxml2库

在linux对XML文件进行增、删、改、查,需要使用库libxml2

这个库可以在地址:ftp.gnome.org/pub/GNOME/sources/libxml2/2.6/ 下载,

我下载的文件是libxml2-2.6.30.tar.gz,将它放到到自己的Linux环境中,解压文件:

tar -xzvf libxml2-2.6.30.tar.gz

进入解压后的文件,依次输入命令安装:

./configure
make
make install

如果想检查安装效果可以输入命令:

make tests

卸载已安装的库可以输入命令

make uninstall

安装后的库,会被安放在两个地方:

*.h文件会被放到地址 /usr/local/include/libxml2/libxml

*.so文件会被放到地址 /usr/local/lib

二、源码一(a.cpp)

a.cpp建立了一个XML文档,根节点List,下面有2个Person,每个Person下有若干属性和若干Achievement作为子结点

#include<stdio.h>

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

int main()
{
    //建立XML文档和根结点
    xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0");
    xmlNodePtr root = xmlNewNode(NULL, BAD_CAST"List");

    //将根节点绑定到XML文档
    xmlDocSetRootElement(doc, root);

    //建立Person结点,为其安装四个属性
    xmlNodePtr nodeTsybius = xmlNewNode(NULL, BAD_CAST"Person");
    xmlNewProp(nodeTsybius, BAD_CAST"Id", BAD_CAST"1001");
    xmlNewProp(nodeTsybius, BAD_CAST"Name", BAD_CAST"Tsybius");
    xmlNewProp(nodeTsybius, BAD_CAST"Sex", BAD_CAST"Male");
    xmlNewProp(nodeTsybius, BAD_CAST"Age", BAD_CAST"23");
    xmlAddChild(root, nodeTsybius);

    //在Person结点下安放子结点,并为子节点添加内容
    xmlNewTextChild(nodeTsybius, NULL, BAD_CAST"Achievement", BAD_CAST"ABC Rank 2");
    xmlNewTextChild(nodeTsybius, NULL, BAD_CAST"Achievement", BAD_CAST"DEF Rank 4");

    xmlNodePtr nodeGalatea = xmlNewNode(NULL, BAD_CAST"Person");
    xmlNewProp(nodeGalatea, BAD_CAST"Id", BAD_CAST"1002");
    xmlNewProp(nodeGalatea, BAD_CAST"Name", BAD_CAST"Galatea");
    xmlNewProp(nodeGalatea, BAD_CAST"Sex", BAD_CAST"Female");
    xmlNewProp(nodeGalatea, BAD_CAST"Age", BAD_CAST"21");
    xmlAddChild(root, nodeGalatea);

    xmlNewTextChild(nodeGalatea, NULL, BAD_CAST"Achievement", BAD_CAST"ABC Rank 1");
    xmlNewTextChild(nodeGalatea, NULL, BAD_CAST"Achievement", BAD_CAST"XYZ Rank 2");
    xmlNewTextChild(nodeGalatea, NULL, BAD_CAST"Achievement", BAD_CAST"MNOP Rank 5");
    
    //保存XML文档
    int nRel = xmlSaveFile("List.xml", doc);
    if(nRel != -1)
    {
        printf("List.xml: Created Successfully!\n");
    }

    //释放资源
    xmlFreeDoc(doc);
    xmlCleanupParser();

    return 0;
}

三、源码二(b.cpp)

b.cpp对a.cpp中建立的XML文档进行修改

#include<stdio.h>
#include<stdlib.h>

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

#define spc(level) PrintSpace(level)

//输出缩进用的空格(4个)
void PrintSpace(int level)
{
    for(int counter = 0; counter < level; counter++)
    {
        printf("    ");
    }
}

//主函数
int main()
{
    //打开XML文件
    xmlDocPtr doc = xmlParseFile("List.xml");
    if(doc == NULL)
    {
        printf("Error: Can not open List.xml\n");
        exit(1);
    }

    //找到首结点
    xmlNodePtr root = xmlDocGetRootElement(doc);
    if(root == NULL)
    {
        printf("Error: Can not find the root!\n");
        exit(1);
    }

    xmlNodePtr person; //Person结点指针
    xmlNodePtr achivm; //Achievement结点指针

    //遍历一个Person结点
    spc(0); printf("Name: %s\n", root -> name);

    person = root -> children;

    //逐个找出属性
    spc(1); printf("Node: %s\n", person -> name);
    spc(2); printf("Id: %s\n", xmlGetProp(person, BAD_CAST "Id")); 
    spc(2); printf("Name: %s\n", xmlGetProp(person, BAD_CAST "Name")); 
    spc(2); printf("Sex: %s\n", xmlGetProp(person, BAD_CAST "Sex")); 
    spc(2); printf("Age: %s\n", xmlGetProp(person, BAD_CAST "Age"));

    //用循环遍历子节点,打印内容
    for(achivm = person -> children; achivm; achivm = achivm -> next)
    {
        spc(3); 
        printf("Node: %s\t", achivm -> name);
        printf("Content: %s\t", (char*)xmlNodeGetContent(achivm));
        printf("End\n");
    }

    spc(1); printf("End\n");

    //一个Person结点遍历结束
    //转到下一个Person结点
    person = person -> next;

    //查看某属性是否与某字符串相等
    if(xmlStrcmp(xmlGetProp(person, BAD_CAST "Name"), (const xmlChar*)"Galate"))
    {
        spc(1); printf(">> The next person is Galatea!\n");
    }
    else
    {
        spc(1); printf(">> The next person is not Galatea!\n");
    }

    //查看某结点是否有某属性
    if(xmlHasProp(person, BAD_CAST "Height"))
    {
        spc(1); printf(">> The node person has attribute: Height!\n");
    }
    else
    {
        spc(1); printf(">> The next person does not have attribute: Height!\n");
    }

    //修改属性(Attribute)
    xmlSetProp(person, (const xmlChar*)"Age", (const xmlChar*)"22");
    spc(1); printf(">> Change Galatea's age from 21 to 22!\n");

    //修改子结点中的内容(Content)
    xmlNodeSetContent(person -> children, (const xmlChar*) "NEW Rank 1");
    spc(1); printf(">> Change Galatea's 1st achievement to NEW Rank 1\n");


    //打印修改后的person结点
    spc(1); printf("Node: %s\n", person -> name);
    spc(2); printf("Id: %s\n", xmlGetProp(person, BAD_CAST "Id")); 
    spc(2); printf("Name: %s\n", xmlGetProp(person, BAD_CAST "Name")); 
    spc(2); printf("Sex: %s\n", xmlGetProp(person, BAD_CAST "Sex")); 
    spc(2); printf("Age: %s\n", xmlGetProp(person, BAD_CAST "Age"));     

    for(achivm = person -> children; achivm; achivm = achivm -> next)
    {
        spc(3); 
        printf("Node: %s\t", achivm -> name);
        printf("Content: %s\t", (char*)xmlNodeGetContent(achivm));
        printf("End\n");
    }

    spc(1); printf("End\n");

    spc(0); printf("End\n");

    xmlFree(achivm);
    xmlFree(person);
    xmlFree(root);
    xmlFree(doc);
    xmlCleanupParser();

    return 0;
}

四、编译

在a.cpp和b.cpp同一个目录下建立一个文件compile.sh,内容如下

#!/bin/sh

echo compiling...

g++ a.cpp -I/usr/local/include/libxml2 -L/usr/local/lib -lxml2 -o a
g++ b.cpp -I/usr/local/include/libxml2 -L/usr/local/lib -lxml2 -o b

echo run a...
./a
cat List.xml

echo run b...
./b

exit 0

在命令行中输入下面命令编译a.cpp和b.cpp

/bin/sh compile.sh

五、运行结果

END

© 著作权归作者所有

共有 人打赏支持
北风其凉

北风其凉

粉丝 118
博文 498
码字总数 463468
作品 4
朝阳
程序员
私信 提问
Libxml2库的编译和使用

Libxml2库提供了C语言解析和构造xml文档的接口,为后台C语言处理程序和前台应用程序提供了一种通用的通迅方式。 本文以libxml2-2.6.30版本来说明Libxml2库的使用方法。 1. 编译库文件 libxml...

mickelfeng
2013/05/18
0
0
Windows环境下libxml2库的使用小结

(1)--环境的搭建,下载与安装LIBXML2和ICONV Libxml2是一个C语言的XML程序库,可以简单方便的提供对XML文档的各种操作,并且支持XPATH查询,以及部分的支持XSLT转换等功能。Libxml2的下载地址...

moki_oschina
2014/08/19
0
0
C++的XML编程经验――LIBXML2库使用指南

写这篇文章的原因有如下几点:1)C++标准库中没有操作XML的方法,用C++操作XML文件必须熟悉一种函数库,LIBXML2是其中一种很优秀的XML库,而且它同时支持多种编程语言;2)LIBXML2库的Tutoria...

mickelfeng
2013/04/08
0
0
LIBXML2库使用指南

C++的XML编程经验――LIBXML2库使用指南 写这篇文章的原因有如下几点:1)C++标准库中没有操作XML的方法,用C++操作XML文件必须熟悉一种函数库,LIBXML2是其中一种很优秀的XML库,而且它同时支...

长平狐
2012/09/03
5.4K
0
solaris下安装pureftp必看和提供修改mysql中FTP密码的代码(原创)

文档太多,我就不写了,写下我troubleshooting中遇到的问题吧 在网上搜索大家在安装apche+php5和libxml2后。启动apache时会报一个启动错误:大概意思就是找不到libxml2的库文件之类的错误。 ...

JavaGG
2009/05/06
378
0

没有更多内容

加载失败,请刷新页面

加载更多

SpringBoot引入第三方jar包或本地jar包的处理方式

在开发过程中有时会用到maven仓库里没有的jar包或者本地的jar包,这时没办法通过pom直接引入,那么该怎么解决呢 一般有两种方法 - 第一种是将本地jar包安装在本地maven库 - 第二种是将本地j...

独钓渔
今天
2
0
五、MyBatis缓存

一、MyBatis缓存介绍 缓存的使用可以明显的加快访问数据速度,提升程序处理性能,生活和工作中,使用缓存的地方很多。在开发过程中,从前端-->后端-->数据库等都涉及到缓存。MyBatis作为数据...

yangjianzhou
今天
2
0
最近研究如何加速UI界面开发,有点感觉了

最近在开发JFinal学院的JBolt开发平台,后端没啥说的,做各种极简使用的封装,开发者上手直接使用。 JBolt开发平台包含常用的用户、角色、权限、字典、全局配置、缓存、增删改查完整模块、电...

山东-小木
今天
3
0
《月亮与六便士》的读后感作文3000字

《月亮与六便士》的读后感作文3000字: 看完英国作家威廉.萨默塞特.毛姆所著《月亮与六便士》(李继宏译),第一疑问就是全书即没提到“月亮”,也没提到“六便士”。那这书名又与内容有什么...

原创小博客
昨天
2
0
微信网页授权获取用户信息(ThinkPHP5)+ 微信发送客服消息(一)

以thinkphp5为实例,创建控制器 class Kf extends Controller { /** * [protected description]微信公众号appid * @var [type] */ protected $appid = "xxxxxxxxxxxxxxx"; /** * [protected......

半缘修道半缘君丶
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部