tinyxml2解析rss文件并存储为txt

参考资料:xml -> rss -> tinyxml -> regex

xml:XML 教程

rss:RSS 教程

tinyxml2:TinyXML-2: TinyXML-2

regex:参考代码中注释
 

要求:

tinyxml2解析rss文件并生成一个 pagelib.txt, 其格式:
 
 

    <doc>
      <docid>1</docid>
      <title> ... </title>
      <link> ...  </link>
      <description> ... </description>
      <content> ... </content>
    </doc>
    <doc>
    <docid>2</docid>
      <title> ... </title>
      <link> ...  </link>
      <description> ... </description>
      <content> ... </content>
    </doc>
    <doc>
      ...
    </doc>

需要解析的rss文件片段:

<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
  <channel>
    <title>36氪</title>
    <language>zh-cn</language>
    <pubDate>2016-10-26 16:53:42</pubDate>
    <generator>36氪 - 让创业更简单</generator>
    <description>为创业者提供最好的产品和服务</description>
    <link><![CDATA[http://36kr.com]]>
    </link>
    <item>
      <author>周天</author>
      <title><![CDATA[被美团收购支付牌照的幕后故事:在“被毁灭”与“被吞并”之间二选一]]>
      </title>
      <category>深度报道</category>
      <link>http://36kr.com/p/5055230.html?ktm_source=feed</link>
      <guid>http://36kr.com/p/5055230.html?ktm_source=feed</guid>
      <link_3g>http://36kr.com/p/5055230.html?ktm_source=feed</link_3g>
      <description><![CDATA[<p>被美团收购,对钱袋宝的CEO孙江涛来说,几乎是绝境逢生。</p><p>去年年初,原本停留在线上的微信、支付宝开始强势介入线下支付,印在小纸片上的二维码,以极低的铺设成本迅速打开局面,使得依靠铺设商户端POS机来收取交易手续费的传统线下收单公司们,陷入穷途末路。</p><p>但意外情况的出现,给了他们一条生路。央行出于监管目的宣称不再发放新牌照,现存的267张支付牌照立刻成为稀缺资源,价格急剧变贵。</p><p>这迫使有支付需求的大公司开始紧张地搜寻牌照,唯品会、小米、恒大、美的都在最近短短几个月内花费重金完成牌照的收购,更有大批二线互联网公司如滴滴、360、乐视和携程也在积极询价,36氪记者甚至在一些微信群中看到公开叫买叫卖支付牌照的现象,这都为第三方支付公司出售变现营造了绝好的窗口期。但这个窗口期不会太长,一旦所有买家完成收购,剩下的牌照价格可能会大幅跳水。</p><p>但对于已经把企业卖给美团点评的孙江涛,总算可以长吁一口气,尘埃落定之后,他和36氪聊了聊他15年的创业经历:<strong> 从最早在功能机时代从事电信SP(增值服务)业务,到2006年卖掉SP业务开始线下收单业务,再到移动互联网时代遭到微信支付宝抢夺市场,他的创业史俨然成为一部支付行业的沉浮简史。</strong></p><p>以下内容基于孙江涛的讲述,由36氪采访整理完成:</p><p><strong>1、功能机时代的支付机会</strong></p><p>我从2001年开始创业,缘起于当时中国移动发布的“移动梦网创业计划”——即允许sp合作伙伴使用中国移动的计费通道来提供增值服务,于是产生了一批依赖该支付通道的内容提供商。我们不打算做内容,但我们发现,通过扣除话费来缴费,电信运营商实际上可以充当支付通道的角色。</p><p>这就让我在其中找到了商业机会,很快就想到,游戏充值也完全有可能通过短信来充值,于是我们就把这个支付通道提供给各大主流游戏公司,再从中赚取差价,这件事做的比较顺利,到了2006年,看出来行业步入中后期,所以把这个业务卖给了中华网,获得2000万美金,完成了第一桶金的积累。后来,神州泰岳和掌趣这些电信增值业务公司都是靠sp业务实现的上市。</p><p>现在回忆,2001年-2006年这6年正是中国经济快速成长的时期——2001年最开始做的时候,中国全部移动手机只有4500万部,2006年我们退出时有五六亿部,行业翻了十倍,就是做的再差再笨,业绩也会增长。</p><p>卖掉没多久,SP行业的红利期就结束了,目前这个行业基本已经不复存在了,原因是移动互联网兴起,就不需要功能机上的Wap、彩信之类的传统支付实现方式,这就是被新技术革命掉的行业,我很幸运地提前完成退出。</p><p>彼时还孵化了“神州付”项目,就是除短信充值之外,用纸质话费卡给游戏充值,因为这个项目跟IDG结缘,2007年年底,跟当时还在IDG担任合伙人的张震在东三环的咖啡厅聊了一个小时,他觉得不错,才一两年就能看到不错的现金流,接着就见了一堆合伙人,被挑战一通之后,我们拿到了220万零五千美金的融资款。后来我再创业、直到这次被美团收购,张震都是我的投资人。</p><p>拿到钱之后怎么用?于是就在寻找新业务,想做网上借款的业务,所以就成立了钱袋宝的前身,但感觉我们的DNA还不适合,没有足够的支付和借贷经验,就停了下来。</p><p><strong>2、一片蓝海的支付市场</strong></p><p>再往后,就出现了“移动支付”的机会。2008年还是Feature phone(功能机)的天下,但已经显现出智能机快速兴起的苗头。那时候我们面临两种选择,一种就是做应用,把PC端应用搬到手机端上来,因为当时觉得手机屏幕小,所以认为手机应用仅仅是PC的子集,没想到会取代PC,而考虑到我们在pc端没有积累,直接做应用不一定有机会,就放弃了这条路。</p><p>但我们在游戏充值上有积累,所以就想沿着支付的路走得更宽。我们也判断,手机支付有重新洗牌机会。在排除做APP内容和手机借贷之后,我们坚定了移动支付的方向。</p><p>在进入支付行业之时,我发现了一个惊人的事实:仅航空领域一年票务的电子交易量就达到1000个亿,同时,航空领域一年的交易规模是4000个亿,这两组数字是不是矛盾的?</p><p>其实不是,原因很简单,从票务公司到一级代理(中航信)、二级代理,需要几道结算,这就增加了钱款流动的次数,整个产业的支付规模就变成4000亿元。从这一点就可以看出来,支付产业非常庞大。</p><p>所以现在来看,选中支付这个方向是对的,但可惜入手时选错了细节:我们想通过B-B-C的模式,即通过银行账户体系来切入C端,等于是帮银行部署手机银行的应用,我们的构想是在手机里装上一个类似U盾的安全硬件,让用户把一个安全芯片放到SIM卡槽里,从而让手机支付得以实现。</p><p>但是,我们高估了用户把一个硬件产品自主装到自己手机里的能力。看起来安装容易,把芯片装到SIM卡槽就搞定了,但用户插错甚至把机器弄坏的情况时有发生,我们甚至还为此给用户赔了几台手机。这也说明,多一个硬件就多一个累赘,让体验下降,因此让商业推广变慢。</p><p>而且,我们也过高估计了推进银行的速度。银行的问题是,虽然理念上支持,但决策周期太漫长,比如跟工商银行谈,要让30个处室来论证,都要出具意见,中间但凡有一个人没看懂或作梗就会把节奏拖慢。</p><p><strong>3、线下收单时代:微小的效率改进,就能带来净利润提升</strong></p><p>这样跑下来,最快的一家银行也花费了我们足足三年时间。这时候已经到了2010年,我们意识到不对劲,钱也烧得所剩不多,必须赶紧换方向。</p><p>好在这一年,我们迎来了一个机会,就是央行要发放支付牌照,于是我们花了六七个月集中人力去申请牌照,在2011年第一批拿到牌照,之后才开始规划收单业务。有了这块收单牌照,我们就可以去商户那里铺我们自己的POS机了,然后收取一定的费率,这就是收单业务。&nbsp;</p><p>转战线下收单市场后,几个月就在财务上打平了,并处于快速增长阶段。那是因为,2008年到2016年这个周期是中国货币增发的阶段,很多行业欣欣向荣。</p><p>而且,人们消费意识提升,线下吃喝玩乐消费需求被激活了,让我们赶上了这波“拉动内需”的潮流。我的感悟是,创业者做业务时候要赶到大势的节奏。我们幸运的地方是每一步都踩在经济周期中有意思的环节。</p><p>作为线下收单的新进入者,调研中我们发现小微商户小门店,没有收单机具,还是现金收款,每家交易规模一个月也就两三万流水,这么小的体量,用传统收单服务方式,都不足以弥补成本。</p><p>所以银行以前不愿意接入小商家,如果中间有一家支付公司集成一大堆小商户,有了更高的交易量,银行是愿意的;从C端看,用户只要有一种银行卡就能在任何商户支付。这样,<strong>就解决了C和B的量级的不对称性,带来了资源集成后的成本下降和效率提高,这是第三方支付的价值。</strong></p><p>因为有央行监管要求,安装POS机要现场拍摄商业环境,营业执照和税务登记证都要拍照,来确定是真实商户。我们的创新之处是把巡检中的定位、拍照、审核程序都首次通过APP来实现,比如商户有安装需求后,我们派单给最近的销售人员,于是提高了效率。&nbsp;</p><p><strong>因为是低毛利的行业,只要效率提高一点,省下来的钱就是净利润,所以微小的技术改进,带来了净利润大幅提升。</strong>到了2015年,我们交易量占整个行业的千分之六七,市场份额还比较小,每年是一千多亿的交易规模,按千分之1.5、1.6的费率算,我们获得的服务费是1.5亿。</p><p><strong>4、微信支付宝开始“降维打击”后&nbsp;</strong></p><p>但2015年上半年出现的几个趋势,让我意识到,这样的好景可能不长。</p><p>首先是同业竞争加剧。这个行业容纳了两百多家支付公司,蛋糕在过去五六年一直变大,每家都有自己的领地,井水不犯河水,暂且相安无事,但最近一两年,就开始短兵相接了,互相都在抢对方的商户。快钱,易宝,汇付天下成为我们主要竞争对手,模式一样,最终就只能拼费率,于是降低了所有人的毛利率。</p><p>还没来得及喘息,我们就发现了一个更可怕的事实:过去两年间,微信通过抢红包迅速实现了C端用户的大数量聚集,银行已经彻底沦为支付宝和微信的通道了。</p><p>比如,原来我们看信用卡账单,会看到在哪个商场消费了多少钱。现在再看账单,就只能看到是通过微信支付和支付宝花了钱,对银行而言,没有任何数据可言,<strong>这样一来,所有的用户消费行为和场景彻底被“短路”了。微信支付宝顺利完成了从线上到线下的入侵。</strong></p><p>通过推动线下扫码,微信、支付宝切走了大量线下pos机的市场份额。<strong>有一句叫“对手毁灭你,与你无关”,可以用来形容我们这个行业发生的事情——就在我们和快钱打得正火热之时,突然发现,连战场都没了,这就是毁灭性的降维打击。</strong></p><p>微信和支付宝之所以势如破竹,是因为从C端着手,部署成本很低,放张纸片二维码就行了,而我们要放几百块钱的机具,抵达过程也需要人工成本。微信完全可以非人工,店铺老板自己就可以去网站申请二维码,打印出来贴在收银台就行,不需要有人上门铺设。所以我们当时判断,微信二维码一定会大量普及。</p><p>微信支付宝撬动用户习惯的策略是,先把五道口、三里屯这些关键区域的全部商户拿下,通过大量烧钱来无死角部署二维码,并补贴所有用户,让用户养成习惯,之后用户再去其他地方,就会迅速迫使其他商家跟进。而且,覆盖过程中不需要更换手机和pos机,价值链条是穿透的,没有太多障碍。&nbsp;</p><p>现在还有一些同行帮支付宝部署机具,短期内确实挣钱了,但简直是与虎谋皮。过去帮银联部署pos机,银联只是裁判,不是运动员,最终还是需要我们,大家是价值链的不同环节。但是,帮微信、支付宝这些支付公司去部署二维码扫码工具就很可笑了,今天还给我们留千分之一的手续费可赚,明天说不定就取消了,这个利润分分钟就会消失,我们始终是被动的。&nbsp;</p><p>第三,行业还有一个变化,现在对我们还没有产生影响,但未来会产生很大影响,那就是Apple Pay的应用直接把支付集成到NFC中,用户体验会非常好,操作效率极高,而且有了安全芯片,安全程度比二维码还高出两个数量级,还能支持大额支付,因此会对传统银行卡刷卡消费业态形成冲击,吃掉我们的增长点。</p><p><strong>5、IPO也不是好出路</strong></p><p>看到这样的趋势之后,我们就想尽快IPO,<strong>通过资本的力量,反复兼并其他选手,把自己做到第一集团,从而实现退出。</strong>其实,在2014年就有四千万的净利润,2015年有五千万,已经符合创业板的上市条件。</p><p>但后来通过和券商、律师会计师沟通,基本结论是业务线有很多创新,都需要一些监管部门出具监管意见,涉及部门太多,也很难拿到通过意见,最终在证监会那里不会被认可,所以我们才放弃了这条路径。</p><p>独立上市未果,但支付市场的剧变依然没有停止,这促使我们今年决定卖掉公司。我们认为没有背景、没有用户量,独立的第三方支付公司会比较悲催,短期内很难找到放量上行的空间。</p><p>支付概念在二级市场还很受欢迎,从春节后,就有30多家上市公司来找我们,我挑选了三五家有实力的做了深度接触。但发现,这几家其实都无法和我们形成协同效应,感觉都是想靠概念来维持业绩,在资本市场讲故事,这和我们的理念不一致。</p><p><strong>6、被美团收购</strong></p><p>因此,互联网公司是我们更想接触的对象,第二梯队的互联网公司普遍都有需求。比如,小米,360,美团,乐视,滴滴,携程和今日头条。</p><p>最开始想卖给小米,但一打听才知道小米已经落实了一张牌照。接下来想接触今日头条,发现他们对支付的诉求不强烈,一年虽有几十亿收入,但都不是靠用户付费产生的,而是来自于B端的广告费。</p><p>后来找到美团,谈得非常友善,一拍即合。本来春节后没多久就谈好了的,但赶上五年牌照到期,需要续展,又拖了几个月才续完,这期间团队做了实验性的磨合,也没对团队披露,大家都以为签了大客户。&nbsp;</p><p>我们铺POS机的时间很晚,快钱、汇付天下都铺完两茬了我们才开始。所以当时在一线城市已经没机会了,我们就选择铺在二三线城市,这也和美团点评形成很大的协同效应。</p><p>我们虽然发展了120万商户,活跃商户也有几十万,但美团点评有6亿C端用户和450万商户,都能让钱袋宝的基本面扩得更宽。自己做第三方支付平台,要积累6亿用户谈何容易,用户不会为了支付而装我的支付工具,但用户会为了京东和美团点评去装,顺手着就把支付干了,竞争不在一个维度上。&nbsp;</p><p>美团点评看中我们两方面的价值:一是全牌照,我们有互联网支付、移动电话支付、收单牌照,还有跨*汇支付牌照,一共四张全国范围的央行支付牌照,这在业内也没几家了;第二,我们团队不错,包括风控、合规、清算等都稳健运行了多年。</p><p>对美团来说,最大的意义是合规,通俗地理解:如果没这张牌照,是不可以管理别人的钱的——如果两个企业之间资金往来是贸易相向的,是一对一的,就不需要支付牌照。但如果涉及到三方,把钱给你,再由你转交到第三人,那么你是在一瞬间代替我管了这笔钱,那么你就需要牌照。</p><p><strong>7 金融对于互联网巨头的意义是什么</strong></p><p>很多人看到蚂蚁金服拥有支付宝,估值非常高。<strong>就会认为支付牌照有很大想象空间,但其实支付牌照只是一个必要条件,不是“放大器”。</strong></p><p><strong>支付宝值钱,是因为拥有阿里体系内的数亿用户,只有当牌照撞击了巨大用户量和刚需消费场景,这张牌照才能产生非常大的价值,否则仅仅就是个牌照。</strong></p><p>大家看到阿里的金融业务赚钱未必会跟进,因为觉得阿里的生态不可复制;但如果京东也做成了,大家都会心动。之前京东金融一拆分出来,估值就是460亿元。于是,百度、美团点评,甚至滴滴、万达都会想去做金融,即使短期内赚不到钱,光是估值和故事就很吓人。</p><p>因为它们有海量用户,各条业务线有现金流动。与其用别人的支付工具,为什么不自己做一个?再不济,也完全可以玩一个资本游戏,装一个支付公司进来,导1亿用户给它,然后进行融资,或者再卖掉,轻松赚回100亿,对于巨头们来说,赚完钱再用回微信、支付宝的支付通道也无关紧要。</p><p>对于我们来说,现阶段最好的结局,可能还是卖掉。在完成交接之后,我会开始新的创业计划,回首向来,过去十几年,捡到的都是小机会,没能成长为巨头,有点遗憾,我们还是希望能做点格局更大的事情。</p>]]>
      </description>
      <pubDate><![CDATA[Wed, 26 Oct 2016 16:53:42 +0800]]>
      </pubDate>
      <source>36氪</source>
    </item>
  </channel>
</rss>

 

思路

xml -> rss -> tinyxml -> regex

根据要求,只需要提取元素<title><link><description><content>,所以只需要关注rss文件的以上四个元素和在tinyxml2作为根节点的<channel>元素。

发现rss文件<description>的内容中存在形如<strong><p>的标签和&nbsp;的多余成分,用正则表达式\<.+?\>|&nbsp;过滤。

代码

#include "tinyxml2.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <regex>
using namespace std;
using namespace tinyxml2;
using std::regex;

struct Rss
{
    string title;
    string link;
    string description;
    string content;
};

class Dictionary
{
public:
    void Rssltem(const std::string& filename);
    void store(const std::string& filename);
private:
    vector<Rss> _Rss;
};

string delete_spilth(string line)
{
    regex rx(R"(\<.+?\>|&nbsp;)");
    return  regex_replace(line, rx, "");
                                      
}

/*
正则表达式R"(\<.+?\>)"在此的作用等价于<.+?>,大意是匹配所有<string>或<char>,string或char必须存在至少一个字符,否则匹配数量为0。  .+?的含义详见此链接     https://www.jb51.net/article/183106.htm
表达式中,\<和\>中的\用来表示<和>只是一个没有任何意义的字符。举个例子[xyz]表示匹配含有xyz的字符串,而/[xyz/]表示匹配含有[xyz]的字符串
R"()则属于c++11的特性,具体见https://segmentfault.com/a/1190000018903666
*/


void Dictionary::Rssltem(const std::string& filename)
{

    //声明
    XMLDocument xml;

    //导入xml文件
    if (xml.LoadFile("36kr.xml") != XML_SUCCESS)
    {
        cout << "导入文件失败" << endl;
        return;
    }

    cout << "导入文件成功" << endl;
    //找到导入的xml的根节点
    //
    XMLElement* rootNode = xml.RootElement();
    if (rootNode == NULL)
    {
        cout << "未找到根节点" << endl;
        return;
    }

    cout << "找到根节点" << endl;
    //读取第一层子节点信息并打印在控制台上
    XMLElement* root_1_channel = rootNode->FirstChildElement("channel");
    XMLElement* root_2_item = root_1_channel->FirstChildElement("item");

    while (root_2_item)
    {
        Rss rss;
        XMLElement* root_3_title = root_2_item->FirstChildElement("title");
        string title = root_3_title->GetText();
        rss.title = title;

        XMLElement* root_3_link = root_2_item->FirstChildElement("link");
        string link = root_3_link->GetText();
        rss.link = link;

        XMLElement* root_3_description = root_2_item->FirstChildElement("description");
        string descr = root_3_description->GetText();
        rss.description = delete_spilth(descr);

        _Rss.push_back(rss);

        root_2_item = root_2_item->NextSiblingElement("item");
    }
    cout << "读取完毕" << endl;

}
void Dictionary::store(const std::string& filename)
{
#ifdef Debug
    cout << "store" << endl;
#endif
    ofstream ofs(filename);
    if (!ofs.good())
    {
        cerr << "打开文件失败" << endl;
    }

    int size = _Rss.size();
    for (int i = 0; i < size; ++i)
    {

        char str_c[32] = { 0 };
        sprintf_s(str_c,sizeof(str_c), "%d", i + 1);
        ofs << "<doc>" << endl;;
        ofs << "    " << "<docid>" << str_c << "</docid>" << endl;;
        ofs << "    " << "<title>" << _Rss[i].title << "</title>" << endl;;
        ofs << "    " << "<link>" << _Rss[i].link << "</link>" << endl;;
        ofs << "    " << "<description>" << _Rss[i].description << "</description>" << endl;;
        ofs << "    " << "<content>" << _Rss[i].content << "</content>" << endl;;
        ofs << "    " << "</doc>" << endl;;
        ofs << endl;
    }
    cout << "写入结束" << endl;
}
int main()
{
    Dictionary fieq;
    fieq.Rssltem("36kr.xml");
    fieq.store("pagelib.txt");
    return 0;
}

 结果:

tinyxml2解析rss文件并存储为txt

 

上一篇:linux之内存:


下一篇:越权漏洞反制钓鱼网站