由于项目需要,这两天在用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文档

        关于XPath的基础知识,可以访问http://www.w3school.com.cn/xpath/index.asp
#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文件的读取及查询的更多相关文章

  1. asp.net 实现对xml文件的 读取,添加,删除,修改

    用于修改站内xml文件 已知有一个XML文件(bookstore.xml)如下:<?xml version="1.0" encoding="gb2312" ...

  2. 使用jq的ajax实现对xml文件的读取

    之前一直在用json来传递数据,但是xml也是不可缺少的,于是开始了xml的征程.xml的一些属性啊之类的在菜鸟教程上列举的已经很详细了,但是却没有前段部分的获取教程,查询资料,遂懂: index.x ...

  3. 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】

    一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...

  4. JDOM方法实现对XML文件的解析

    首先要下载JDOM.jar包,下载地址:http://download.csdn.net/detail/ww6055/8880371 下载到JDOM.jar包之后导入到工程中去. 实例程序: book ...

  5. 用DOM4J包实现对xml文件按属性分离。

    转自本人博客:http://www.xgezhang.com/dom4j_xml_separata.html dom4j是一个Java的XML API.类似于jdom.用来读写XML文件的. dom4 ...

  6. Android平台中实现对XML的三种解析方式

    本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...

  7. Java代码加密与反编译(二):用加密算法DES修改classLoader实现对.class文件加密

    Java代码加密与反编译(二):用加密算法DES修改classLoader实现对.class文件加密 二.利用加密算法DES实现java代码加密 传统的C/C++自动带有保护机制,但java不同,只要 ...

  8. 【java】 linux下利用nohup后台运行jar文件包程序

    Linux 运行jar包命令如下: 方式一: java -jar XXX.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 ...

  9. Linux下查找包含BOM头的文件和清除BOM头命令 2014-08-16 12:30:50

    Linux下查找包含BOM头的文件和清除BOM头命令 2014-08-16 12:30:50 分类: 系统运维 查找包含BOM头的文件,命令如下: 点击(此处)折叠或打开 grep -r -I -l ...

随机推荐

  1. [转] docker基础知识之挂载本地目录

    [From] https://blog.csdn.net/huludan/article/details/52641090 https://my.oschina.net/piorcn/blog/324 ...

  2. dcoker machine

    Docker Machine是一个安装和管理 Docker 的工具, 它有自己的命令行工具:docker-machine.Docker Machine简化了Docker的安装和远程管理, 不仅可以管理 ...

  3. Flask项目出现html文件无法自动补全

    默认情况下我们使用Pycharm专业版创建一个Flask项目时就会自动创建一个简单的项目结构,Pycharm会自动关联起文件的语法,模版等.而自己手动创建的文件并没有关联起来.这就会出现上面说的无法补 ...

  4. vi命令——修改文件内容

    以下内容转载自http://blog.csdn.net/bruce0532/article/details/7842384 vi编辑器是所有Unix及Linux系统下标准的编辑器,介绍一下它的用法和一 ...

  5. zookeeper 常用命令

    服务管理 启动ZK服务: zkServer.sh start 查看ZK状态: zkServer.sh status 停止ZK服务: zkServer.sh stop 重启ZK服务: zkServer. ...

  6. Linux下Makefile的automake生成全攻略--转

    http://www.yesky.com/120/1865620.shtml 作为Linux下的程序开发人员,大家一定都遇到过Makefile,用make命令来编译自己写的程序确实是很方便.一般情况下 ...

  7. hdu 2845——Beans——————【dp】

    Beans Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  8. BlackLowKey主题CSS

    /* Minification failed. Returning unminified contents. (151,61): run-time error CSS1062: Expected se ...

  9. 【MSDN】 SqlServer DBCC解析

    汇总学习下SqlServer的DBCC指令. DBCC:Transact-SQL 编程语言提供 DBCC 语句以作为 SQL Server 的数据库控制台命令. 数据库控制台命令语句可分为以下类别. ...

  10. win10x系统下的Git下载安装

    git安装和使用百度一下就有,官方地址https://git-scm.com/book/zh/v1/起步-安装-Git 但是说的并不是很详细,自己记录一下, 首先我们去官网下载一个git 有两个下载地 ...