[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的两个 ...
随机推荐
- java的Spring学习2- junit和mock
<!-- 引用Mock --> <dependency> <groupId>org.mockito</groupId> <artifactId&g ...
- spark java wordCount实例
1. 算子 package com.test; import java.util.Arrays; import java.util.List; import org.apache.spark.Spar ...
- c# datagridview 相关操作。
string[] newRow = {"long","d","b"}; Gridview.Rows.Insert(Gridview.Rows ...
- CentOS 6.2出现Disk sda contains BIOS RAID metadata解决方法
今天在安装CentOS 6.2的时候,当进到检测硬盘的时候,总是过不去,报错如下: Disk sda contains BIOS RAID metadata, but is not part of a ...
- Python学习 day08
一.open打开文件 文件操作包含以下三个步骤: 1.文件路径 2.编码方式 3.操作方式:‘’只读‘’.“只写”.“读写” 等 1.只读 r (mode默认值) 例: f = open('d:\py ...
- 基于原生态Hadoop2.6 HA集群环境的搭建
hadoop2.6 HA平台搭建 一.条件准备 软件条件: Ubuntu14.04 64位操作系统, jdk1.7 64位,Hadoop 2.6.0, zookeeper 3.4.6 硬件条件 ...
- Eclipse的企业开发时常用快捷键使用、优化配置(博主推荐)
不多说,直接上干货! 一.简介 eclipse可谓是Java开发界的神器,基本占据了大部分的Java开发市场,而且其官方还对其他语言提供支持,如C++,Ruby,JavaScript等等.为什么使用它 ...
- 重新分析connection reset by peer, socket write error错误原因
上次写<connection reset by peer, socket write error问题排查>已经过去大半年,当时把问题"敷衍"过去了. 但是此后每隔一段时 ...
- What's the difference between @Component, @Repository & @Service annotations in Spring?
@Component is equivalent to <bean> @Service, @Controller , @Repository = {@Component + some mo ...
- Wp及Windows应用商店程序Logo生成器
在开发wp或windows应用商店程序时,需要制作不同分辨率下的logo,往往不同分辨率下的logo仅仅是图片尺寸或图片的内边距不同,为了快速生成不同分辨率下的图片,减少工作量,于是就自己动手开发了个 ...