[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的两个 ...
随机推荐
- Angular4+NodeJs+MySQL 入门-02 MySql操作类
NodeJs操作MySQL类 此类封装了几个常用的方法:插入,更新,删除,查询,开启事务,事务提交,事务回滚等操作.有一这个类,操作MYSQL就方便多了. 批处理,存储过程等方法还没有添加,因为觉得目 ...
- Java Swing笔记
想到了解一下GUI主要是想用来做点小工具,记录一些笔记. 文本框自动换行和滚动条 private static JTextArea addJTextArea(JPanel panel, int x, ...
- PowerDesigner 16.5 安装和卸载教程【含有安装文件】
1 下载 下载地址:https://pan.baidu.com/s/1kqly0d8qU-QluEagXwh53g 密码:n1a3 下载之后目录结构如下: 2 安装教程 1 安装 1.双击安装文件,如 ...
- Java网站开发的一些问题以及解决(cookie消失,上传头像,js等)
1.首先是cookie的问题,很多人都是遇到了将数据存储到cookie中并且add到response之中,但是还有返回其他页面或者刷新页面cookie消失的情况,除了设置cookie的存活时间外, 还 ...
- D3(v5) in TypeScript 坐标轴之 饼状图生成
饼状图生成时依旧遇到了类型问题,记录如下: import * as d3 from 'd3'; import * as React from 'react'; class TestGraph exte ...
- WCF的入门教程dome(一)
一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NE ...
- Android的存储方式
Android常见的四种存储方式: 1. SharePreference 2. File 3. ContentProvider 4. SQLite 第一种: 保存在应用程序私有的文件夹下---- 只有 ...
- bzoj 5340: [Ctsc2018]假面
Description 题面 Solution 生命值范围比较小,首先维护每一个人在每个血量的概率,从而算出生存的概率,设为 \(a[i]\) 询问时,只需要考虑生存的人数,可以 \(DP\) 设 \ ...
- 解决npm install安装慢的问题
国外镜像会很慢 可用 get命令查看registry npm congfig get registry 原版结果为 http://registry.npmjs.org 用set命令换成阿里的镜像就可以 ...
- C#学习笔记12
1.在使用反射时,反射可以绕过安全访问级别(private.protected)修饰的类或属性,来获取需要的信息. 2.泛型的反射:可以使用Type.ContainsGenericParameters ...