场景:

1.在软件需要保存一些配置项时,使用数据库的话比较复杂,查看内容也不容易.纯文本文件对utf8字符支持也不好.

2.这时候使用xml是最佳选择,使用跨平台库libxml2。

3.基于xpath的保存方式对保存局部内容非常方便。

4.参考例子xpath2.c

     #include <stdio.h>
#include <assert.h>
#include <string>
#include <iostream>
#include <map> #include "libxml/tree.h"
#include "libxml/parser.h"
#include "libxml/xpath.h"
#include "libxml/xpathInternals.h"
#include "libxml/xmlsave.h" using namespace std; static void _UpdateXpathNodes(xmlNodeSetPtr nodes, const xmlChar* value)
{
int size;
int i; assert(value);
size = (nodes) ? nodes->nodeNr : ;
for(i = size - ; i >= ; i--)
{
assert(nodes->nodeTab[i]);
xmlNodeSetContent(nodes->nodeTab[i], value);
if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL)
{
nodes->nodeTab[i] = NULL;
}
}
} static int _UpdateWithXpath(xmlXPathContextPtr xpathCtx,const char* key,const char* value)
{
xmlXPathObjectPtr xpathObj; xpathObj = xmlXPathEvalExpression(BAD_CAST key, xpathCtx);
if(!xpathObj)
{
fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", key);
return -;
}
_UpdateXpathNodes(xpathObj->nodesetval, BAD_CAST value);
xmlXPathFreeObject(xpathObj);
return ;
} static int _UpdateXml(const char* path,map<string,string>& keyValue)
{
xmlDocPtr doc;
xmlXPathContextPtr xpathCtx;
doc = xmlParseFile(path);
if (!doc)
{
fprintf(stderr, "Error: unable to parse file \"%s\"\n", path);
return(-);
} /* Create xpath evaluation context */
xpathCtx = xmlXPathNewContext(doc);
//1.注意,这里根Node有声明xmlns,那么必须加下边这句,相应的xpath要加前缀 /c:container/c:rootfiles
//xmlXPathRegisterNs(xpathCtx,BAD_CAST"c",BAD_CAST"urn:oasis:names:tc:opendocument:xmlns:container");
if(!xpathCtx)
{
fprintf(stderr,"Error: unable to create new XPath context\n");
xmlFreeDoc(doc);
return(-);
}
//3.update
map<string,string>::iterator iter;
map<string,string>::iterator end = keyValue.end();
for(iter = keyValue.begin();iter!= end;iter++)
{
cout << "word: " << iter->first << ", count: " << iter->second << endl;
_UpdateWithXpath(xpathCtx,iter->first.c_str(),iter->second.c_str());
} xmlXPathFreeContext(xpathCtx);
//4.save
xmlSaveCtxtPtr saveCtxtPtx = xmlSaveToFilename(path,"UTF-8",XML_SAVE_FORMAT);
if(!saveCtxtPtx)
{
xmlFreeDoc(doc);
return -;
} if(- == xmlSaveDoc(saveCtxtPtx,doc))
{
xmlFreeDoc(doc);
return -;
}
xmlSaveClose(saveCtxtPtx);
//xmlDocDump(stdout, doc);
//5.free
xmlFreeDoc(doc);
return ;
} int UpdateXml(const char* path,map<string,string>& keyValue)
{
/* Init libxml */
xmlInitParser();
int res = _UpdateXml(path,keyValue);
xmlCleanupParser();
return res;
} int main(int argc, char *argv[])
{
printf("Hello, world\n");
map<string,string> m;
m["/doc/parent/discarded/@info"] = string("info attri");
m["/doc/parent/discarded[2]"] = string("change second discarded text 中文");
int ret = UpdateXml("xpath2.res",m);
assert(!ret);
ret = UpdateXml("xpath2.res",m);
assert(!ret);
ret = UpdateXml("xpath2.res",m);
assert(!ret);
return ;
}

xpath2.res

    <?xml version="1.0" encoding="UTF-8"?>
<doc>
<parent>
<discarded info="test">discarded</discarded>
<preserved/>
This text node must be discarded
<discarded>test</discarded>
<preserved>
content1
<child1/>
<child2>content2</child2>
<preserved>too</preserved>
<child2>content3</child2>
<preserved/>
<child2>content4</child2>
<preserved/>
<child2>content5</child2>
content6
</preserved>
</parent>
</doc>

xpath2.res

    <?xml version="1.0" encoding="UTF-8"?>
<doc>
<parent>
<discarded info="info attri">discarded</discarded>
<preserved/>
This text node must be discarded
<discarded>change second discarded text 中文</discarded>
<preserved>
content1
<child1/>
<child2>content2</child2>
<preserved>too</preserved>
<child2>content3</child2>
<preserved/>
<child2>content4</child2>
<preserved/>
<child2>content5</child2>
content6
</preserved>
</parent>
</doc>

[libxml2]_[XML处理]_[使用libxml2的xpath特性修改xml文件内容]的更多相关文章

  1. Java&Xml教程(三)使用DOM方式修改XML文件内容

    DOM解析方式也可用于修改XML数据,我们可以使用它完成新增元素.删除元素.修改元素值.修改元素属性等操作. 我们的XML文件,内容如下: employee.xml <?xml version= ...

  2. xml学习_上篇

    xml简介: XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. xml小示例: /************************ ...

  3. Spring_MVC_教程_快速入门_深入分析

    Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门  资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf Spring ...

  4. 权限模块_使用权限_实现主页面的效果_显示左侧菜单&只显示有权限的菜单项

    权限模块__使用权限__实现主页面的效果 HomeAction.java public class HomeAction extends ActionSupport { public String i ...

  5. 系统管理模块_岗位管理_实现CRUD功能的具体步骤并设计Role实体

    系统管理模块_岗位管理_实现CRUD功能的具体步骤并设计Role实体 1,设计实体/表 设计实体 --> JavaBean --> hbm.xml --> 建表 设计Role实体 p ...

  6. [libcurl]_[0基础]_[使用libcurl下载大文件]

    场景: 1. 在Windows编程时, 下载http页面(html,xml)能够使用winhttp库,可是并非非常下载文件,由于会失败. 由此引出了WinINet库,无奈这个库的稳定性比較低,使用样例 ...

  7. mybatis3.1-[topic-18-20]-_映射文件_参数处理_单个参数&多个参数&命名参数 _POJO&Map&TO 三种方式及举例

    笔记要点出错分析与总结 /**MyBatis_映射文件_参数处理_单个参数&多个参数&命名参数 * _POJO&Map&TO 三种方式及举例 _ * 单个参数 : #{ ...

  8. 基于samba实现win7与linux之间共享文件_阳仔_新浪博客

    基于samba实现win7与linux之间共享文件_阳仔_新浪博客 然后启动samba执行如下指令: /dev/init.d/smb start 至此完成全部配置.

  9. 浅谈 Underscore.js 中 _.throttle 和 _.debounce 的差异

    Underscore.js是一个很精干的库,压缩后只有5.2KB.它提供了几十种函数式编程的方法,弥补了标准库的不足,大大方便了JavaScript的编程. 本文仅探讨Underscore.js的两个 ...

随机推荐

  1. [转] 最简单实现跨域的方法:使用nginx反向代理

    [From] http://blog.jobbole.com/90975/ 什么是跨域 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全 ...

  2. scraoy之日志等级处理

    一.Scrapy的日志等级 - 在使用scrapy crawl spiderFileName运行程序时,在终端里打印输出的就是scrapy的日志信息. - 日志信息的种类: ERROR : 一般错误 ...

  3. 让android系统中任意一个view变成进度条

    1.效果 2.进度条背景drawable文件 结束后可以恢复原背景. <?xml version="1.0" encoding="utf-8"?> ...

  4. docker 创建容器时遇到的坑

    坑一.时区问题 在创建系统镜像时,比如centos,会默认最小安装,并且时区默认的是UTC 所以在下好centos的原始镜像后,最好再重新构建一个新的镜像 # 命令 docker pull cento ...

  5. Python 垃圾回收机制(转)

    概述 python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略. 引用计数 Python语言默认采用的垃圾收集机制是『引用计数法 Reference Counting』,该算法最早 ...

  6. 路由器中带宽设置(Bandwidth) 20MHZ/40MHZ

    原文是英文的,在这里:http://routerguide.net/setting-up-20-mhz-or-40-mhz-bandwidth-how-to-improve-wifi-network- ...

  7. Iterator遍历 (遍历集合)

    迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为“轻量级”对象,因为创建它的代价小. Java中的I ...

  8. 修改Android解锁界面

    解锁界面效果类似如下 其实这也是我后面做出的效果,样机因为没有ROOT不好调试截图,功能是将解锁的图标添加了最近运行的运用的图标,这样的话更方便用户去使用 1.分析 1.1.Android锁屏功能分析 ...

  9. zookeeper 常用命令

    服务管理 启动ZK服务: zkServer.sh start 查看ZK状态: zkServer.sh status 停止ZK服务: zkServer.sh stop 重启ZK服务: zkServer. ...

  10. Win10内置应用恢复初始状态

    和Win8/Win8.1相同,Win10也内置了很多默认Windows应用,比如计算器.天气.人脉.Groove音乐.电影和电视.邮件和日历.Edge浏览器等.一般情况下,这些应用不会有太大的问题,但 ...