由于项目需要,这两天在用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. phantomjs的和谷歌浏览器的简单使用

    一.phantomjs的简单使用 ''' 什么是phantomJs:无界面的浏览器 ''' from selenium import webdriver from time import sleep ...

  2. archlinux安装交叉编译工具链

    1. 在/usr/local下新建文件夹:arm  [guo@archlinux local]$sudo mkdir arm 2. 将交叉编译工具拷贝到arm文件夹中  [guo@archlinux ...

  3. Mercurial stuck “waiting for lock”, tortoisehg pull版本卡住在等待 解决办法

    最近使用hg的时候,拖取版本一直卡住不动.报错类似waiting for lock on working directory of xxxx held by ''. 原本以为是网络不好或者hg安装有问 ...

  4. h5 的video视频控件

    h5 的video视频控件 由于html5的流行,其中的video视频的使用很流行,使得可恨的IE9也能与时俱进了. video所支持的格式有mp4.ogg和wav三种. 例: HTML5 Video ...

  5. PIE SDK专题制图打开模板

    1.    功能简介 在PIE SDK中,所有的制图元素.视图范围以及排版等都可以保存成一个模板,以供多次重复使用.使用时只需要打开该模板,加载相应数据,就可以直接出图了,省去了重复制作图幅的麻烦,方 ...

  6. js的apply和call

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Python(xlrd、xlwt模块)操作Excel实例(一)

    一.前言 关于Python的xlrd.xlwt模块的使用,推介另一位博客主的博文:https://www.cnblogs.com/zhoujie/p/python18.html 这篇里面有详细介绍这两 ...

  8. mysql记录数据库中重复的字段的数据

    SELECT    SUM(co)FROM    (        SELECT            telephone,            count(telephone) AS co     ...

  9. TreeMap和TreeSet简单应用

    建一个实体类并实现Comparable接口重写compareTo方法 public class pojo implements Comparable<pojo> { private int ...

  10. c#中日期的处理

    DateTime.Now.ToShortDateString()//只取日期DateTime.Now.ToLongTimeString();//只取时间搞定DateTime.Now.ToShortTi ...