随便写的一个小程序:将有道阅读导出的rss列表转换成Foxmail的rss兼容的导入文件

原来使用google reader,结果改版后感觉特别别扭就转到有道阅读了,最近为了快速收取邮件,使用了Foxmail,然后看见下面有个rss功能,感觉还算不错,就像将有道阅读导入Foxmail,结果发现Foxmail弱爆了,竟然由于有道导出的xml的node的属性顺序不同导入后都成了文件夹,一个一个加也挺麻烦的,就想写个转换程序,反正比较简单,就是简单的换些属性的顺序。

#include <iostream>
#include <tchar.h>
#include <string>
using namespace std;
#include "rapidxml/rapidxml.hpp"
#include "rapidxml/rapidxml_iterators.hpp"
#include "rapidxml/rapidxml_print.hpp"
#include "rapidxml/rapidxml_utils.hpp"
using namespace rapidxml;
#ifdef _UNICODE
typedef wstring tstring;
typedef wofstream tofstream;
typedef wifstream tifstream;
#define tcout wcout
#else
typedef string  tstring;
typedef ofstream tofstream;
typedef ifstream tifstream;
#define tcout cout 
#endif

bool parseXml(xml_node<TCHAR>* &pParentNode,tstring &strSwitched);
bool ReadTheFile(tstring strFileFullPath,tstring& strReadContent);
int _tmain(int argc,TCHAR *argv[],TCHAR *envp[])
{
    tcout.imbue(std::locale( "chs"));
     if (argc != 2)
     {
         tcout<<_T("参数有误")<<endl;
         system("pause");
         return 0;
     }
    tcout<<_T("正在读取文件......")<<endl;
    tstring strSrcFile = argv[1]; //文件名

    //fetch the path
    tstring strDestFile;
    size_t nFound = strSrcFile.rfind(_T('/'));
    if (nFound == tstring::npos)
    {
        nFound = strSrcFile.rfind(_T('\\'));
    }
    if (nFound == tstring::npos)
    {
        strDestFile = _T("C:/switched.opml");
    }
    else
    {
        strDestFile = strSrcFile.substr(0,nFound+1);
        tstring strName = strSrcFile.substr(nFound+1,tstring::npos);
        int nFind = strName.rfind(_T('.'));
        if (nFind == tstring::npos)
        {
            strDestFile = _T("C:/switched.opml");
        }
        else
        {
            strName.replace(nFind,1,_T("_switched."));
            strDestFile += strName;
        }
    }
    //end fetch the path
    tstring strRead;
    if (!ReadTheFile(strSrcFile,strRead))
    {
        tcout<<_T("读取文件失败")<<endl;
        system("pause");
        return 0;
    }
    tcout<<_T("读取文件成功")<<endl;
    tcout<<_T("正在转换文件......")<<endl;
    xml_document<TCHAR> xml;
    try
    {
        xml.parse<0>(const_cast<TCHAR*>(strRead.c_str()));
    }
    catch (...)
    {
        tcout<<_T("源文件格式有误!")<<endl;
        system("pause");
        return 0;
    }
    xml_node<TCHAR> *pRootNode = xml.first_node(_T("opml"));
    if (pRootNode == NULL)
    {
        tcout<<_T("源文件格式有误!")<<endl;
        system("pause");
        return 0;
    }
    xml_node<TCHAR> *pBodyNode = pRootNode->first_node(_T("body"));
    if (pBodyNode == NULL)
    {
        tcout<<_T("源文件格式有误!")<<endl;
        system("pause");
        return 0;
    }
    tstring strSwitched;
    xml_node<TCHAR> *pOutlineNode = pBodyNode->first_node(_T("outline"));
    if (!parseXml(pOutlineNode,strSwitched))
    {
        tcout<<_T("源文件格式有误!")<<endl;
        system("pause");
        return 0;
    }
    strSwitched = _T("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<opml version=\"1.0\">\n\t<head>\n\t\t<title>Subscription in Foxmail</title>\n\t</head>\n\t<body>\n") + strSwitched;
    strSwitched += _T("\t</body>\n</opml>");
    xml_document<TCHAR> xmlSave;
    try
    {
        xmlSave.parse<0>(const_cast<TCHAR*>(strSwitched.c_str()));
    }
    catch (...)
    {
        tcout<<_T("转换失败!")<<endl;
        system("pause");
        return 0;
    }
    tstring szText;
    rapidxml::print(back_inserter<>(szText),xmlSave);
    tcout<<_T("转换成功!")<<endl;
    tofstream outStream(strDestFile.c_str(),ios_base::out | ios_base::binary);
    outStream<<szText;
    outStream.close();
    tcout<<_T("保存文件在");
    tcout<<strDestFile<<endl;
    system("pause");
    return 0;
}

bool parseXml(xml_node<TCHAR>* &pParentNode,tstring &strSwitched)
{
    xml_attribute<TCHAR> *pTextAttr = NULL;
    xml_attribute<TCHAR> *pTitleAttr = NULL;
    xml_attribute<TCHAR> *pXmlUrlAttr = NULL;
    xml_attribute<TCHAR> *pHtmlUrlAttr = NULL;
    while (pParentNode != NULL)
    {
        pTextAttr = pParentNode->first_attribute(_T("text"));
        pTitleAttr = pParentNode->first_attribute(_T("title"));
        pXmlUrlAttr = pParentNode->first_attribute(_T("xmlUrl"));
        pHtmlUrlAttr = pParentNode->first_attribute(_T("htmlUrl"));
        if (pTextAttr != NULL && pTitleAttr != NULL)
        {
            if (pXmlUrlAttr == NULL) //文件夹
            {
                if (pHtmlUrlAttr != NULL) //error
                {
                    return false;
                }
                else
                {
                    xml_node<TCHAR>* pFistChild = pParentNode->first_node(_T("outline"));
                    strSwitched += _T("<outline title=\"");
                    strSwitched += pTitleAttr->value();
                    strSwitched += _T("\" text=\"");
                    strSwitched += pTextAttr->value();
                    strSwitched += _T("\">\n");
                    if (pFistChild == NULL)
                    {
                        strSwitched += _T("</outline>\n");
                    }
                    else
                    {
                        if (parseXml(pFistChild,strSwitched))
                        {
                            strSwitched += _T("</outline>\n");
                        }
                        else
                        {
                            return false;
                        }
                    }                    
                }
            }
            else    //不是文件夹
            {
                strSwitched += _T("<outline htmlUrl=\"");
                strSwitched += pHtmlUrlAttr->value();
                strSwitched += _T("\" xmlUrl=\"");
                strSwitched += pXmlUrlAttr->value();
                strSwitched += _T("\" version=\"RSS\" type=\"rss\" title=\"");
                strSwitched += pTitleAttr->value();
                strSwitched += _T("\" text=\"");
                strSwitched += pTextAttr->value();
                strSwitched += _T("\"/>\n");
            }
        }
        else
        {
            return false;
        }
        pParentNode = pParentNode->next_sibling(_T("outline"));
    }
    return true;
}

bool ReadTheFile(tstring strFileFullPath,tstring& strReadContent)
{
    tifstream inStream(strFileFullPath.c_str(),ios_base::in | ios_base::binary);
    inStream.seekg (0, ios::end);
    int length = inStream.tellg();
    inStream.seekg (0, ios::beg);

    TCHAR* pBuf = new TCHAR[length+1];
    inStream.read(pBuf,length);
    inStream.close();
    pBuf[length] = _T('\0');
    strReadContent = pBuf;
    delete []pBuf;

    return true;
}

 

基本可以使用了,但是有时源文件中title或者text有特殊字符,会是转换后的文件有问题。另外也没考虑全面,先这样吧,睡觉了,明天去公司报道啦

posted @ 2012-07-02 00:46  likebeta  阅读(876)  评论(0编辑  收藏  举报