c++使用xpath解析xml --tinyxpath

来源:互联网 发布:flash 9插件 for mac 编辑:程序博客网 时间:2024/05/16 16:06

起因

    最近一直做Qt项目,一次偶然的机会了解到了xpath,使用非常方便,便做下总结。
    对于xml理解,之前一直认为仅仅是一个标记性语言,有一定的树形结构,对xml的解释分为dom和sax方式,其余并未有更深入的理解。之前项目中有用到xml,主要是解析itunes的xml文件并导入到我们的播放器软件中。1,使用时,采用sax方式逐步解析,发现比较繁琐(一级一级地寻找下一节点,代码耦合性非常强);2,后面又在代码中运用到了json数据,发现相对于xml的这中解析方式,大为方便;3,再后来自己研究了下xpath,发现其实xml也可以很方便~

准备

    既然采用xpath,而且我又是采用的c++,于是搜索了下,发现tinyxpath可以很好地满足我的需求。其实之前本来准备用QXmlQuery的,后面发现并不是很好用(可能是我没用好,下次有空可以细细研究下~//TODO,另外在qml中本身就支持xpath,这里暂且不表)。
    首先自然是下载tinyxpath,链接http://tinyxpath.sourceforge.net/。下载后配置很简单,直接打开tinyxpath.sln编译就行了。后面运行时注意要define下TIXML_USE_STL;_CRT_SECURE_NO_WARNINGS;(其中CRT_SECURE_NO_WARNINGS,用于消除一个copy相关的error,如果报错vs会提示你去定义这个宏;TIXML_USE_STL用于将TIXML_STRING定义为std::string)

使用例子:

    那么,重点来了,上例子:

#include "stdafx.h"#include "tinyxml.h"#include "xpath_static.h"struct PresentStruct {    int id;    std::string name;};int _tmain(int argc, _TCHAR* argv[]){    TiXmlDocument * XDp_doc = new TiXmlDocument;    TiXmlElement * XEp_main;    XDp_doc->LoadFile("D:\\present_client.xml");    XEp_main = XDp_doc->RootElement();    //TiXmlElement * XEp_sub = XEp_main->FirstChildElement("/presents/present"); 这里也可以正常去获取某个节点    for (int i = 0, j = TinyXPath::i_xpath_int(XEp_main, "count(/presentInfo/presents[1]/present)"); i < j; ++i) {        std::string strTmp("/presentInfo/presents/present");        PresentStruct presentS;        presentS.id = TinyXPath::i_xpath_int(XEp_main, "/presentInfo/presents[1]/present[1]/@id"); // 这里xpath字串需要根据i进行组装,最后把presentS收集到一个容器中即可    }}

    看是不是觉得很简单。
附上对应的xml文件

<?xml version="1.0" encoding="UTF-8"?><presentInfo>  <version id="9.81"/>  <presents tab="0">    <present id="11" name="mm"/>    <present id="12" name="gg"/>      </presents>  <presents tab="1">    <present id="11" name="mm"/>    <present id="12" name="gg"/>      </presents><presentInfo>

    具体的xpath语法可以参照http://www.w3school.com.cn/xpath/xpath_syntax.asp

0 0