您的位置:首页 > 运维架构 > Linux

Linux下使用C++的Boost库和Tiny-xml2工具解析xml文件

2019-01-18 18:05 651 查看

源码链接:https://github.com/Dortmund-Reus/RssReader

一、Boost库的使用:

1.Boost官方教程:
https://www.boost.org/doc/libs/1_46_1/doc/html/boost_propertytree/tutorial.html
教程很短而且说的很清楚,简单易懂,给的例子运行一下也没有问题。
2.Boost的regex_replace()方法的使用:
首先要加上头文件:
#include <boost/regex.hpp>
一个简单的示例:

这里<(\S*?)[^>]>.?|<.*? />是用来过滤html标记的正则表达式,我们的目标就是去掉context里面的<…….>,只保留hello world!
regex_replace()的三个参数分别为:被处理的字符串、正则表达式、替换匹配内容所用的字符串(这里我要去掉,所以用的是””)。
但是编译有个大坑:

看到这满屏的字符,我的内心是崩溃的。
原来,在使用boost/regex的时候,要加上库编译(前面那个官方示例没用到boost/regex,直接正常编译就完事了):


输出结果是正确的。

二、获取指定目录下的所有文件

这部分代码是从网上download下来稍加修改做的。
getName.h的内容如下:

适用于Linux和Windows系统。
getName.cc文件中,最重要的是getFiles这个方法(也是提供了Linux和Windows两个版本,我嫌代码太长就删除了Windows的部分):

在getFiles方法中,我们传入一个表示路径的参数cate_dir,最后返回的是一个string的vector,每个元素的内容就是指定路径下的文件名。

在main函数中,定义了一个char型数组存放当前路径,getcwd是C++自带的一个方法,头文件是<unistd.h>,它可以获取当前文件所在的目录的路径。我们的xml存放在sources文件夹中,所以我要对current_address稍加修改。
目录结构:

测试结果:

三、Tiny-xml2的使用

github文档:https://github.com/leethomason/tinyxml2
我做的第一件事,就是把文档给翻译了一遍,毕竟也没有多长。
之后,就下载了源码,并且尝试看了看 tinyxml2.cc,结果看完四个小例子之后,发现这个源码有两千多行,果断放弃……(不过前四个例子倒是挺有用的,可以很快就了解基本用法)。
现在,准备工作都做完了,可以正式开始了。

首先是头文件,这里就是定义了一个结构体,其中有一个writeToFile()方法,用于把一个结构体的内容全部输出到文件中去。
RssReader类中定义了一个RssItem类型的vector,存放一个文件中所有的RssItem.parseRss方法用于解析一个文件,dump负责输出文件。
RssReader.cc中是具体的实现:
第一个方法是WriteToString方法,它的第一个参数是一个XMLElement指针,Rss文件中我这里定义的是item级别的元素,第二个是元素的名字,我需要的有”title”,”link”,”description”,”content:encoded”.
为了避免出现html标签不存在的情况,我加了一个if语句,如果找到了想要的子元素,就去获取它的内容,并且用之前的去除html标记的语句对它的内容进行去格式化。

第二个方法是WriteToRssItem:

这个方法纯粹是为了缩短函数体而写的,在这里我们把element_name传给上面的WriteToString方法,而被改变的string就是RssItem的四个成员。
这两个方法写好了以后,就可以开始parseRss方法的编写了:

在这个方法中,我们先定义一个XMLDocument对象,然后让它加载指定的xml文件并进行解析,这一步是在loadFile函数中进行的。
为了确定是rss文件,我又加了一个if语句,否则会发生segment fault.文件加载成功后,获取它的第一个item元素,通过NextSiblingElement方法对整个xml文件中的item元素进行遍历。
对于每个item元素,我们将它的内容写入一个RssItem(这里注意WriteToRssItem的形参一定要是引用,不然没用),然后把这个RssItem存入RssReader对象的_rss成员中,至此,一个xml文件的解析已经完成。
接下来是dump方法:

在dump方法中,我们遍历_rss,将它的每一个元素都用writeToFile方法写入文件,注意两个点:
1)用append方式写入文件;
2)在方法末尾,记得清空_rss并关闭文件输出流。
writeToFile的实现如下,比较简单:

最后是main函数,前面就是获取路径,稍微要注意的地方是重命名的时候,取子串这个函数——substr的第二个参数是指定的长度,而不是结束位置!
看看输出的结果:

以上。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: