场景:

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. node.js知识点提取

    javascript是脚本语言,脚本语言都需要一个解析器才能运行.

  2. pandas强化练习

    这篇文章写得更好:http://wittyfans.com/coding/%E5%88%A9%E7%94%A8Pandas%E5%88%86%E6%9E%90%E7%BE%8E%E5%9B%BD%E4 ...

  3. PIE SDK打开Micaps数据

    1. 功能简介 Micaps数据是气象信息处理和天气预报制作中的一种气象数据格式.其包含多种气象信息产品(地面常规气象观测数据产品.高空常规气象观测数据产品等),目前Micaps数据被Micaps软件 ...

  4. PIE SDK算法的异步调用

    1.算法功能简介 异步方法一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作.异步方法通常会在另外一个线程中,“真实”地执行着.整个过程,不会阻碍调用者的工作. PIE SDK支持算法功能的执 ...

  5. 转 .net 获取IP地址的三个方法的比较

    获取用户IP地址的三个属性的区别(HTTP_X_FORWARDED_FOR,HTTP_VIA,REMOTE_ADDR)   一.没有使用代理服务器的情况: REMOTE_ADDR = 您的 IP    ...

  6. shell 实现文件改名

    修改文件名可以有不同的命令方式,mv 可以实现,但是使用rename 这种专业的改名字很好 对于单个的文件,可以直接使用以上的命令,那如果有大量的类似格式的文件名需要修改成其他格式的,该如何呢? 创建 ...

  7. unity消息队列

    解决一些当一些消息事件需要处理时,但是 相应的系统还没有初始化来解决的问题 每个系统执行层也有一个消息队列,这样系统没有做好初始化,不执行就好了. 参考:http://blog.csdn.net/ws ...

  8. JDBC的PreparedStatement启动事务使用批处理executeBatch()

    JDBC使用MySQL处理大数据的时候,自然而然的想到要使用批处理, 普通的执行过程是:每处理一条数据,就访问一次数据库: 而批处理是:累积到一定数量,再一次性提交到数据库,减少了与数据库的交互次数, ...

  9. 你还在把Java当成Android官方开发语言吗?Kotlin了解一下!

    导语:2017年Google IO大会宣布使用Kotlin作为Android的官方开发语言,相比较与典型的面相对象的JAVA语言,Kotlin作为一种新式的函数式编程语言,也有人称之为Android平 ...

  10. spring-boot 1.4.x遇到的cpu高的问题

    如果你的spring-boot应用里tomcat线程耗cpu较高,并主要耗在做读取jar的操作上(堆栈类似下面),可能跟我们遇到同样的问题. CRC32.update(byte[], int, int ...