C++Day13 tinyxml2解析rss文件

一、任务与思路

使用tinyxml解析rss文件,使用std::regex(正则表达式)去除html标签,并生成一个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>
 1 // 参考接口
 2 
 3 struct RssItem{
 4     string title;
 5     string link;
 6     string description;
 7     string content;
 8 };
 9 
10 class RssReader{
11 public:
12     RssReader(){};
13 
14     //解析xml文件,存入vector
15     void parseRss(const char *filename);
16 
17     //将容器的信息保存到文件中
18     void dump(const string &filename);
19 
20 private:
21     vector<RssItem> m_rss;
22 };

 RSS文件的格式:

<rss>
    <channel>
       <item>
       <title>xxx</title>
      <link>   </link>
       <description>   </description>
      <content:encoded>   </content:encoded>
       </item>
       <item>
         <title>  </title>
         <link>   </link>
         <description>   </description>
         <content:encoded>   </content:encoded>
       </item>
       <item>
        ...
       </item>
    </channel>
</rss>

解题思路:使用tinyxml2这个第三方库进行解析,所以可通过阅读源码看timyxml2如何解析第三方库,解析完成一个item后,通过正则表达式去除HTML标签,然后再去读第二个item,最后就是遍历vector,讲读取到的信息存到另外一个文件

二、陌生第三方库的学习

1 XMLDocument xml;  // 1、创建xml类,读取xml文件
2 xml.LoadFile(filename); // 2、读取xml文件  LoadFile传入的要是C风格字符串
3 XMLElement *rss = xml.RootElement(); //3、拿到xml文件的根节点rss
4 XMLElement *channel = rss->FirstChildElement("channel");  //4、拿到channel节点
5 XMLElement *item = channel->FirstChildElement("item"); //5、拿到item节点

解析item中的内容并保存

1 XMLElement *item_title = item->FirstChildElement("title");  //获取title中的内容
2 rss_item.title = item_title->GetText();  //保存节点的内容

正则表达式去除html标签

1 regex reg("<[^>]*>");  
2 //std::regex中的regex_replace方法   regex_replace() :用格式化的替换文本替换出现的正则表达式
3 rss_item.description = regex_replace(rss_item.description, reg, "");

三、代码实现

 1 //获取Rss文件中channel节点下item节点的内容,存入结构体vector
 2 void RssReader::parseRss(const char *filename){
 3 
 4     XMLDocument xml; // 1、声明xml类,读取xml文件
 5     xml.LoadFile(filename); // 2、读取xml文件  LoadFile传入的要是C风格字符串
 6     XMLElement *rss = xml.RootElement(); //3、拿到xml文件的根节点rss
 7     XMLElement *channel = rss->FirstChildElement("channel");  //4、拿到channel节点指针
 8     XMLElement *item = channel->FirstChildElement("item"); //5、拿到item节点
 9 
10     while(item){
11         RssItem rss_item;  //数据保存到结构体
12         regex reg("<[^>]*>");  //正则表达式去除html标签
13 
14         //获取title节点指针,内容保存到结构体变量
15         XMLElement *item_title = item->FirstChildElement("title");
16         rss_item.title = item_title->GetText();  //保存节点的内容
17 
18         //获取link节点指针,内容保存到结构体变量
19         XMLElement *item_link = item->FirstChildElement("link");
20         rss_item.link = item_link->GetText();
21 
22         //获取desc节点指针,内容保存到结构体变量
23         XMLElement *item_description = item->FirstChildElement("description");
24         rss_item.description = item_description->GetText();
25 
26         rss_item.description = regex_replace(rss_item.description, reg, ""); //去除html标签
27 
28         XMLElement *item_content = item->FirstChildElement("content:encoded");
29         rss_item.content = item_content->GetText();
30 
31         rss_item.content = regex_replace(rss_item.content, reg, "");
32 
33        m_rss.push_back(rss_item);  //存入结构体
34        item = item->NextSiblingElement(); //寻找下一个item节点
35     }
36 }
37 
38 //内容按指定格式输出到文件
39 void RssReader::dump(const string &filename){
40    
41     ofstream ofs(filename);
42     if(!ofs.good()){
43         cerr << "ofstream is not good" << endl;
44         return;
45     }
46 
47     for(size_t idx = 0; idx < m_rss.size(); ++idx){
48         ofs << "<doc>" << "\n"
49             << "\t" << "<docid>" << idx + 1 << "</docid>" << "\n"
50             << "\t" << "<title>" << m_rss[idx].title << "</title>" << "\n"
51             << "\t" << "<link>" << m_rss[idx].link << "</link>" << "\n"
52             << "\t" << "<description>" << m_rss[idx].description << "</description>" << "\n"
53             << "\t" << "<content>" << m_rss[idx].content << "</content>" << "\n"
54             << "</doc>" << endl;
55     }
56     ofs.close();
57 }

测试代码

 1 #include"tiny.h"
 2 
 3 
 4 int main(int argc, char **argv)
 5 {
 6 
 7     RssReader s1;
 8     s1.parseRss("coolshell.xml");
 9 
10     s1.dump("pagelib.txt");
11     return 0;
12 }

编译时要与tinyxml2.cpp一起编译

posted @ 2023-01-27 21:07  晚安地球人1  阅读(201)  评论(0)    收藏  举报