libxml2
1 声明指针:                              文档指针(xmlDocPtr),结点指针(xmlNodePtr);
2 得到文档doc:         xmlReadFile
3 得到根结点root_node: xmlDocGetRootElement
4 结点操作:
1)获得到结点值:                 xmlNodeGetContent(对应于xmlFree)
2)遍历:
指向下一个结点:           xmlNodePtr ->children
结点值:                            xmlNodePtr->name,
结点内遍历:                   xmlNodePtr->next
5 释放内存:                            xmlFreeDoc,xmlFree

今天介绍的方法为使用Dom树解析,将给出两个实例,说明如何使用Libxml2遍历xml文档和使Xpath获取特定结点的内容值:
程序使用的xml文档为:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<node1>content of node 1</node1>
<node3 attribute="yes">node has attributes</node3>
<node4>other way to create content</node>
</root>

遍历程序代码:
#include <iostream>
#include <libxml/parser.h>
#include <libxml/tree.h>
using namespace std;

int main(int argc,char** argv)
{
xmlDocPtr doc=NULL;
xmlNodePtr cur=NULL;
char* name=NULL;
char* value=NULL;

xmlKeepBlanksDefault (0);

if(argc<2)
{
cout<<"argc must be 2 or above."<<endl;
return -1;
}

doc=xmlParseFile(argv[1]);//创建Dom树
if(doc==NULL)
{
cout<<"Loading xml file failed."<<endl;
exit(1);
}

cur=xmlDocGetRootElement(doc);//获取根节点
if(cur==NULL)
{
cout<<"empty file"<<endl;
xmlFreeDoc(doc);
exit(2);
}

//walk the tree
cur=cur->xmlChildrenNode;//get sub node
while(cur !=NULL)
{
name=(char*)(cur->name);
value=(char*)xmlNodeGetContent(cur);
cout<<"name is: "<<name<<", value is: "<<value<<endl;
xmlFree(value);
cur=cur->next;  
}

xmlFreeDoc(doc);//释放xml解析库所用资源
xmlCleanupParser();
return 0;
}

说明:
1. 当使用dom树来解析xml文档时,由于默认的方式是把节点间的空白当作第一个子节 点,所以为了能和常说的第一个子节点相符,需调用xmlKeepBlanksDefault (0)函数来忽略这种空白。
2. 对于使用xmlChar* xmlNodeGetContent(xmlNodePtr cur)函数获取节点内容后,必须调用xmlFree()来对所分配的内存进行释放。

使用Xpath获取特定结点的内容:
#include <iostream>
#include <string>
using namespace std;

#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>

int main(int argc,char** argv)
{
xmlDocPtr doc;
xmlXPathContextPtr xpathCtx;
xmlXPathObjectPtr xpathObj;
xmlNodeSetPtr nodeset;
string xpathExpr;
char* val=NULL;
int size,i;

if(argc<2)
{
cout<<"argc must be 2 or above."<<endl;
return -1;
}

doc = xmlParseFile(argv[1]);
if (doc == NULL)
{
cout<<"Error: unable to parse file: "<<argv[1]<<endl;    
return -1;
}

xpathCtx = xmlXPathNewContext(doc);
if(xpathCtx == NULL)
{
cout<<"Error: unable to create new XPath context"<<endl;
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
return -2;
}

xpathExpr="/root/node3";
xpathObj = xmlXPathexpression_r_r((const xmlChar*)(xpathExpr.c_str()), xpathCtx);
if(xpathObj == NULL)
{
cout<<"Error: unable to uate xpath expression_r_r"<<xpathExpr<<endl;
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
return -3;
}

nodeset=xpathObj->nodesetval;
if(xmlXPathNodeSetIsEmpty(nodeset))
{
cout<<"No such nodes."<<endl;
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
return -4;
}

//get the value    
size = (nodeset) ? nodeset->nodeNr : 0;
for(i = 0; i <size; i++)
{
val=(char*)xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);        
cout<<"the results are: "<<val<<endl;
xmlFree(val);
}

//Cleanup of XPath data
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);

xmlFreeDoc(doc);
xmlCleanupParser();
return 0;
}

我在使用的过程中,犯了错误,没有使用 xmlFree(val),也没有使用 xmlCleanupParser(),当然更没有使用 xmlKeepBlanksDefault (0);最后还是使用了valgrind来定位内存泄露问题!

提示:xmlCleanupParser()不要调用两次,否则就会出现coredump;
# gdb -c core.18659  
... ...
Program terminated with signal 6, Aborted.
... ...
(gdb)   bt
#0  0x0000003aeec30265 in ?? ()
#1  0x0000003aeec31d10 in ?? ()

libxml使用实例相关推荐

  1. xml c libxml类库使用

    xml 参考地址: http://jianlee.ylinux.org/Computer/C/libxml.html 实例: /* * ================================ ...

  2. 前端开发基础知识汇总

    一.HTML 1.前言与常用标签 浏览器 内核 备注 IE Trident IE.猎豹安全.360极速浏览器.百度浏览器 firefox Gecko 可惜这几年已经没落了,打开速度慢.升级频繁.猪一样 ...

  3. Spring Cloud微服务系统架构的一些简单介绍和使用

    Spring Cloud 目录 特征 云原生应用程序 Spring Cloud上下文:应用程序上下文服务 引导应用程序上下文 应用程序上下文层次结构 改变Bootstrap的位置Properties ...

  4. MySQL 5.5.35 单机多实例配置详解

    一.前言 二.概述 三.环境准备 四.安装MySQL 5.5.35 五.新建支持多实例的配置文件(我这里配置的是四个实例) 六.初始化多实例数据库 七.提供管理脚本 mysqld_multi.serv ...

  5. linux mysql 实例详解_MySQL 多实例详解

    目录 一.基本概念 1.MySQL多实例 就是在一台机器上面开启多个不同的端口,运行多个MySQL服务进程.这些MySQL多实例公用一套安装程序,使用不同的(也可以是相同的)配置文件,启动程序,数据文 ...

  6. php xml对象解析_php解析xml 的四种简单方法(附实例)

    XML处理是开发过程中经常遇到的,PHP对其也有很丰富的支持,本文只是对其中某几种解析技术做简要说明,包括:Xml parser, SimpleXML, XMLReader, DOMDocument. ...

  7. mysql 5.5.35 单机多实例配置详解_MySQL 5.5.35 单机多实例配置详解

    一.前言 二.概述 三.环境准备 四.安装MySQL 5.5.35 五.新建支持多实例的配置文件(我这里配置的是四个实例) 六.初始化多实例数据库 七.提供管理脚本 mysqld_multi.serv ...

  8. MySQL 多实例详解

    MySQL多实例配置方法 1.单一配置文件 2.多配置文件. 二.实战步骤: 1.同步时间 2.准备mysql依赖包 3.环境准备 3.1添加mysql用户 3.2编译安装mysql 4.安装MySQ ...

  9. 超简单的mysql多实例布置

    一.基本概念 mysql下载:http://mirrors.sohu.com/mysql/MySQL-5.5/ 1.MySQL多实例 就是在一台机器上面开启多个不同的端口,运行多个MySQL服务进程. ...

最新文章

  1. poj2456 Aggressive cows(二分查找)
  2. C++中内存分配、函数调用和返回值问题
  3. 重置密码遇到ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using passwor:yes)问题
  4. docker安装mysql及相关配置、运行细节和常见报错解决方案
  5. JFreeChart 1.0.6 用户开发指南(中文)
  6. GenericUDF使用流程记载(转载+自己整理)
  7. 如何使用python多线程_Python3如何使用多线程升程序运行速度
  8. Pyinstaller打包: 将资源文件或文件夹打包到最后生成的exe中
  9. Ajax(2)--Ajax核心工作机制 你忘记了吗?
  10. ESET Smart Security 3.0667与WindowsXP Sp3冲突
  11. java/php/net/python基于Java的校园一卡通管理系统
  12. 2022年北京航空航天大学计算机考研复试分数线
  13. 人工智能发展史(读书笔记)
  14. python 类调用不存在的方法_找不到Python方法,但在类中定义
  15. 第二章:真分数理论(真分数模型:概念、假设、平行测验)
  16. k8s paas部署
  17. 33.大数据可视化技术--datav、echarts
  18. AQI空气质量分析与预测
  19. c语言写易语言支持库6,易语言编写支持库
  20. 日志收集Agent,阴暗潮湿的地底世界

热门文章

  1. python-docx 设置Table 边框样式、单元格边框样式
  2. ReflectionTestUtils.invokeMethod方法的使用
  3. Centos7、Redhat7 重置root密码
  4. 0 13 amp 0 17c语言,急等网址跳转大神,无用网址尾巴处理:index.php?id=13amp;amp;rew...
  5. R语言ggplot2可视化:使用geom_step可视化阶梯图、阶梯线图、可视化分组阶梯线图、自定义填充不同分组的阶梯线图(filled geom_step)
  6. JAVA与C、C++比较
  7. 减轻运维人员工作压力?一招轻松实现无人值守
  8. 用累积分布函数(CDF)计算期望
  9. c语言中的warn函数用法,关于c ++:MSVC等同于__attribute__((warn_unused_result))?
  10. 云服务器搭建好,出现 拒绝了我们的连接请求。