linux下使用libxml2实现对xml文件的读取及查询
由于项目需要,这两天在用C++做XML文件解析的工作。在linux下有个很方便的操作xml文件的库——libxml2,它提供了一套创建和查询xml文件的C语言的接口。这篇博客主要介绍如何使用libxml2读取并解析xml文件。
下载并安装libxml2
下载地址:ftp://xmlsoft.org/libxml2/
下载最新的版本,我下载的是libxml2-2.9.1.tar.gz。下载后将文件解压到合适的位置,进入解压后的目录。
编译命令非常简单(注意:如果configure文件没有可执行权限,增加可执行权限):
./configure
make
make install
此时libxml2相关的头文件应该在/usr/local/include/libxml2目录下,libxml2相关的库文件应该在/usr/local/lib目录下。
解析XML文档的两种方式
在使用libxml2进行XML文档的解析时,非常推荐使用XPath语言实现,如果把XML文件看作数据库的话,那么XPath就可被视为sql,我们只要构造一定格式的语句就可查询到相关结果,而在在libxml2中使用Xpath是非常简单的。当然我们也可以直接通过libxml2相关接口从跟节点出发,根据整个xml的父子节点关系定位到相关节点进行查询。下面我将分别对这两种方式进行介绍。
我们使用下面的xml测试用例:
<?xml version="1.0" encoding="ISO-8859-1"?> <bookstore> <book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book> <book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book> </bookstore>
直接使用libxml2接口解析XML文档
#include <stdio.h>
#include <stdlib.h>
#include <libxml/parser.h>
#include <libxml/tree.h> int main (int argc , char **argv)
{
xmlDocPtr pdoc = NULL;
xmlNodePtr proot = NULL, pcur = NULL;
/*****************打开xml文档********************/
xmlKeepBlanksDefault(0);//必须加上,防止程序把元素前后的空白文本符号当作一个node
pdoc = xmlReadFile ("test.xml", "UTF-8", XML_PARSE_RECOVER);//libxml只能解析UTF-8格式数据 if (pdoc == NULL)
{
printf ("error:can't open file!\n");
exit (1);
} /*****************获取xml文档对象的根节对象********************/
proot = xmlDocGetRootElement (pdoc); if (proot == NULL)
{
printf("error: file is empty!\n");
exit (1);
} /*****************查找书店中所有书籍的名称********************/
pcur = proot->xmlChildrenNode; while (pcur != NULL)
{
//如同标准C中的char类型一样,xmlChar也有动态内存分配,字符串操作等 相关函数。例如xmlMalloc是动态分配内存的函数;xmlFree是配套的释放内存函数;xmlStrcmp是字符串比较函数等。
//对于char* ch="book", xmlChar* xch=BAD_CAST(ch)或者xmlChar* xch=(const xmlChar *)(ch)
//对于xmlChar* xch=BAD_CAST("book"),char* ch=(char *)(xch)
if (!xmlStrcmp(pcur->name, BAD_CAST("book")))
{
xmlNodePtr nptr=pcur->xmlChildrenNode;
while (pcur != NULL)
{
if (!xmlStrcmp(nptr->name, BAD_CAST("title")))
{
printf("title: %s\n",((char*)XML_GET_CONTENT(nptr->xmlChildrenNode)));
break;
}
} }
pcur = pcur->next;
} /*****************释放资源********************/
xmlFreeDoc (pdoc);
xmlCleanupParser ();
xmlMemoryDump ();
return 0;
}
具体流程我已经在代码中详细注释,这里就不单独拿出来解释。
使用XPath语言解析XML文档
#include <stdio.h>
#include <stdlib.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <libxml/xmlmemory.h>
#include <libxml/xpointer.h> xmlXPathObjectPtr getNodeset(xmlDocPtr pdoc,const xmlChar *xpath)
{
xmlXPathContextPtr context=NULL;//XPath上下文指针
xmlXPathObjectPtr result=NULL; //XPath结果指针
context = xmlXPathNewContext(pdoc); if(pdoc==NULL){
printf("pdoc is NULL\n");
return NULL;
} if(xpath){
if (context == NULL) {
printf("context is NULL\n");
return NULL;
} result = xmlXPathEvalExpression(xpath, context);
xmlXPathFreeContext(context); //释放上下文指针
if (result == NULL) {
printf("xmlXPathEvalExpression return NULL\n");
return NULL;
} if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
xmlXPathFreeObject(result);
printf("nodeset is empty\n");
return NULL;
}
} return result;
} int main (int argc , char **argv){
xmlDocPtr pdoc = NULL;
xmlNodePtr proot = NULL; /*****************打开xml文档********************/
xmlKeepBlanksDefault(0);//必须加上,防止程序把元素前后的空白文本符号当作一个node
pdoc = xmlReadFile ("test.xml", "UTF-8", XML_PARSE_RECOVER);//libxml只能解析UTF-8格式数据 if (pdoc == NULL)
{
printf ("error:can't open file!\n");
exit (1);
} /*****************获取xml文档对象的根节对象********************/
proot = xmlDocGetRootElement (pdoc); if (proot == NULL)
{
printf("error: file is empty!\n");
exit (1);
} /*****************查找书店中所有书籍的名称********************/
xmlChar *xpath = BAD_CAST("//book"); //xpath语句
xmlXPathObjectPtr result = getNodeset(pdoc, xpath); //查询XPath表达式,得到一个查询结果
if (result == NULL)
{
printf("result is NULL\n");
exit (1);
} if(result)
{
xmlNodeSetPtr nodeset = result->nodesetval; //获取查询到的节点指针集合
xmlNodePtr cur; //nodeset->nodeNr是集合元素总数
for (int i=0; i < nodeset->nodeNr; i++)
{
cur = nodeset->nodeTab[i];
cur = cur->xmlChildrenNode; while (cur != NULL)
{
//如同标准C中的char类型一样,xmlChar也有动态内存分配,字符串操作等 相关函数。例如xmlMalloc是动态分配内存的函数;xmlFree是配套的释放内存函数;xmlStrcmp是字符串比较函数等。
//对于char* ch="book", xmlChar* xch=BAD_CAST(ch)或者xmlChar* xch=(const xmlChar *)(ch)
//对于xmlChar* xch=BAD_CAST("book"),char* ch=(char *)(xch)
if (!xmlStrcmp(cur->name, BAD_CAST("title"))) {
printf("title: %s\n",((char*)XML_GET_CONTENT(cur->xmlChildrenNode)));
break;
} cur = cur->next;
}
} xmlXPathFreeObject(result);//释放结果指针
} /*****************释放资源********************/
xmlFreeDoc (pdoc);
xmlCleanupParser ();
xmlMemoryDump (); return 0;
}
具体流程我已经在代码中详细注释,这里就不单独拿出来解释。
更加详细的libxml2接口,可以访问http://xmlsoft.org/html/libxml-tree.html
编译程序并运行
编译上述程序
g++ search1.cpp -I/usr/local/include/libxml2 -L/usr/local/lib -lxml2 -o search1
g++ search2.cpp -I/usr/local/include/libxml2 -L/usr/local/lib -lxml2 -o search2
运行程序及运行结果
运行./search1
显示如下结果:
title: Harry Potter
title: Learning XML
运行./search2
显示如下结果:
title: Harry Potter
title: Learning XML
来自:http://blog.csdn.net/l_h2010/article/details/38639143
linux下使用libxml2实现对xml文件的读取及查询的更多相关文章
- asp.net 实现对xml文件的 读取,添加,删除,修改
用于修改站内xml文件 已知有一个XML文件(bookstore.xml)如下:<?xml version="1.0" encoding="gb2312" ...
- 使用jq的ajax实现对xml文件的读取
之前一直在用json来传递数据,但是xml也是不可缺少的,于是开始了xml的征程.xml的一些属性啊之类的在菜鸟教程上列举的已经很详细了,但是却没有前段部分的获取教程,查询资料,遂懂: index.x ...
- 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】
一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...
- JDOM方法实现对XML文件的解析
首先要下载JDOM.jar包,下载地址:http://download.csdn.net/detail/ww6055/8880371 下载到JDOM.jar包之后导入到工程中去. 实例程序: book ...
- 用DOM4J包实现对xml文件按属性分离。
转自本人博客:http://www.xgezhang.com/dom4j_xml_separata.html dom4j是一个Java的XML API.类似于jdom.用来读写XML文件的. dom4 ...
- Android平台中实现对XML的三种解析方式
本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...
- Java代码加密与反编译(二):用加密算法DES修改classLoader实现对.class文件加密
Java代码加密与反编译(二):用加密算法DES修改classLoader实现对.class文件加密 二.利用加密算法DES实现java代码加密 传统的C/C++自动带有保护机制,但java不同,只要 ...
- 【java】 linux下利用nohup后台运行jar文件包程序
Linux 运行jar包命令如下: 方式一: java -jar XXX.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 ...
- Linux下查找包含BOM头的文件和清除BOM头命令 2014-08-16 12:30:50
Linux下查找包含BOM头的文件和清除BOM头命令 2014-08-16 12:30:50 分类: 系统运维 查找包含BOM头的文件,命令如下: 点击(此处)折叠或打开 grep -r -I -l ...
随机推荐
- 【Python】ACL限制结果检测
最近帮客户做ACL的限制检测,也就是客户对一些站点做了acl限制,只有省内或内网可以访问,然后让我 去验证acl做的是否正确,简单写了个粗略的脚本,分享下,不足之处日后改进(如多线程等),脚本如下: ...
- Python异常基础
一.常见异常及场景举例 1.AssertionError 断言失败,断言是调试中常用(表示自己并不常用┑( ̄Д  ̄)┍)手段 举例: def foo(s): n = int(s) assert n ! ...
- CSS 单行 多行文本溢出显示省略号
单行文本 overflow: hidden; text-overflow:ellipsis; white-space: nowrap; 多行文本溢出显示省略号: <style type=&quo ...
- web app与app的区别,即html5与app的区别
公司准备要做一个项目,是p2p配资的app.在网上问了一些人后,发现有的是直接有html5做好后,用软件封装的.之前我学过app的开发,当时Android版本的,知道开发Android app时写的代 ...
- 学习总结——docker
1.docker 配置 docker 安装 docker 修改默认存储位置 docker 命令详解(run篇) docker 命令详解(cp篇) 2.docker 镜像相关资料 docker 把容器c ...
- 【Tensorflow】 Object_detection之配置Training Pipeline
参考:Configuring an object detection pipeline 1.config文件 配置好的config文件存放路径:object_detection/samples/con ...
- c#实现wifi连接器
前言 一般正常情况下都会用windows自带的wifi连接,但是为了给用户更好的体验,或者有时候需要检测wifi状态,还是需要集成到项目中态. 原理 1.微软自带Native Wifi API,不过是 ...
- DotNetCore跨平台~xUnit和测试报告
在进入dotnet core时代之后,测试驱动开发TDD的主要工具不再是微软的nunit,取而代之的是更通用的xunit,微软把它集成到了dotnetcore的项目里,在安装完成vs2017之后,你可 ...
- js 省份城市二级动态联动的例子
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- Win10新建分区
今天忽然觉得将系统分为四个盘,有点无法将分类分开,所以增加了几个分区: 1.windows+X键在弹出的对话框中选择磁盘管理,进入如下界面: 2.如果你想从某个盘分出一些内存建立一个新的分区,就在这个 ...