[libxml2]_[XML处理]_[使用libxml2的xpath特性修改xml文件内容]
场景:
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文件内容]的更多相关文章
- Java&Xml教程(三)使用DOM方式修改XML文件内容
DOM解析方式也可用于修改XML数据,我们可以使用它完成新增元素.删除元素.修改元素值.修改元素属性等操作. 我们的XML文件,内容如下: employee.xml <?xml version= ...
- xml学习_上篇
xml简介: XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. xml小示例: /************************ ...
- Spring_MVC_教程_快速入门_深入分析
Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门 资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf Spring ...
- 权限模块_使用权限_实现主页面的效果_显示左侧菜单&只显示有权限的菜单项
权限模块__使用权限__实现主页面的效果 HomeAction.java public class HomeAction extends ActionSupport { public String i ...
- 系统管理模块_岗位管理_实现CRUD功能的具体步骤并设计Role实体
系统管理模块_岗位管理_实现CRUD功能的具体步骤并设计Role实体 1,设计实体/表 设计实体 --> JavaBean --> hbm.xml --> 建表 设计Role实体 p ...
- [libcurl]_[0基础]_[使用libcurl下载大文件]
场景: 1. 在Windows编程时, 下载http页面(html,xml)能够使用winhttp库,可是并非非常下载文件,由于会失败. 由此引出了WinINet库,无奈这个库的稳定性比較低,使用样例 ...
- mybatis3.1-[topic-18-20]-_映射文件_参数处理_单个参数&多个参数&命名参数 _POJO&Map&TO 三种方式及举例
笔记要点出错分析与总结 /**MyBatis_映射文件_参数处理_单个参数&多个参数&命名参数 * _POJO&Map&TO 三种方式及举例 _ * 单个参数 : #{ ...
- 基于samba实现win7与linux之间共享文件_阳仔_新浪博客
基于samba实现win7与linux之间共享文件_阳仔_新浪博客 然后启动samba执行如下指令: /dev/init.d/smb start 至此完成全部配置.
- 浅谈 Underscore.js 中 _.throttle 和 _.debounce 的差异
Underscore.js是一个很精干的库,压缩后只有5.2KB.它提供了几十种函数式编程的方法,弥补了标准库的不足,大大方便了JavaScript的编程. 本文仅探讨Underscore.js的两个 ...
随机推荐
- [jQuery] 在线引用地址
百度静态资源公共库: http://libs.baidu.com/jquery/1.9.1/jquery.js jQuery网站: http://code.jquery.com/jquery-1.9. ...
- 使用Tomcat搭建一个可以通过公网访问的服务器(转)
转自:http://wenku.baidu.com/link?url=kGLhiO1xiiepXa9Q2OJDmm6Zr8dQmpSYYPVTFmc3CZtD6Z7HvFi2miCYDiQdTYF2T ...
- 网站ico那点事儿
一. 如何获取某个网站的favicon.ico http://moco.imooc.com/player/report.html 今天看到这个网站上,左侧的小图片挺好看的,想弄下来,检查源码,也没有看 ...
- IDEA 导入cordova3.5工程目录注意事项
IDEA 导入cordova3.5工程目录注意事项 1 eclipse很不稳定,有很多小问题.平时我自己用idea,但是当用cordova3.5创建好工程目录是,用eclipse导入时没有问题的.但是 ...
- 数据库和AI的一次火花
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由宗文 发表于云+社区专栏 | 导语 通过历史数据,基于时间序列来预测未来. 我们生活中很多数据是有时间维度的.比如说天气或者股票价格. ...
- 坐标深圳 | Kubernetes!我要用这样的姿势拥抱你
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 从去年至今,容器.Kubernetes话题的热度就持续不减,有人说基于容器 +Kubernetes 的新型 PaaS 将会成为云计算的主流: ...
- FZU 1922——非主流——————【技巧题】
非主流 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status P ...
- JavaScript 监听回车事件
JS监听某个输入框 //回车事件绑定 $('#search_input').bind('keyup', function(event) { if (event.keyCode == "13& ...
- HDU 5011 NIM博弈
http://www.cnblogs.com/exponent/articles/2141477.html http://acm.hust.edu.cn/vjudge/contest/122814#p ...
- 2018.10.16 NOIP模拟赛解题报告
心路历程 预计得分:\(100 + 100 + 20 = 220\) 实际得分:\(100 + 100 + 30 = 230\) 辣鸡模拟赛.. T1T2都是一眼题,T3考验卡常数还只有一档暴力分. ...