Создание XML-файла от текстового ввода


Я надеялся, что код читается, как есть. Я, наверное, могу просто печатать XML, используя потоки, но у меня есть другие причины для использования библиотеки.

Пожалуйста, предложить какие-либо материалы о том, как улучшить дизайн программы/структуры.

Заголовок файла

#ifndef GEN_XML
#define GEN_XML

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <vector>
#include <sstream>

typedef std::string stringType;
typedef std::vector<stringType> stringVector;
typedef std::vector<int> integerVector;

class gen_xml
{
private:
    int previousTime;
    int tempTime;
public:
    stringVector text_file;
    integerVector time_ms;
    stringVector text_info;
public:
    gen_xml():previousTime(1),tempTime(2) {};

    virtual int validate(int argc,char* argv[]);

    virtual void showInput(int argc,char* argv[]);

    virtual bool validateFileExtention(stringType fname,stringType ext);

    virtual int getAbsoluteTime(stringType value);

    virtual void getData(char* argv[]);

    virtual stringType toString(int num);

    virtual void generateXML(stringVector text_file,integerVector time_ms,char* FileName);

};

#endif  // GEN_XML

Файл cpp

#include "tinyxml.h"
#include "tinystr.h"
#include "gen_xml.h"
using namespace std;


int main(int argc,char* argv[])
{
    gen_xml req;
    if(req.validate(argc,argv))
    {
        req.getData(argv);
        req.generateXML(req.text_info,req.time_ms,argv[2]);
    }
    cout<<"Done"<<endl;
    return 0;
}
void gen_xml::generateXML(stringVector text_file,integerVector time_ms,char* FileName)
{
    TiXmlDeclaration* declaration = new TiXmlDeclaration("1.0", "UTF-8", "no");//Create DTD
    TiXmlDocument* doc = new TiXmlDocument;
    doc->LinkEndChild(declaration);

    TiXmlElement* msg;

    TiXmlElement * root = new TiXmlElement( "tags" );
    doc->LinkEndChild( root );
    for(int i=0; i<(int)text_file.size(); i++)
    {
        TiXmlElement * msgs = new TiXmlElement( "metatag" );
        msgs->SetAttribute("event", "onCuePoint");
        msgs->SetAttribute("overwrite", "true");
        root->LinkEndChild( msgs );

        msg = new TiXmlElement( "name" );

        msg->LinkEndChild( new TiXmlText("CuePoint"+toString(i) ));
        msgs->LinkEndChild( msg );

        msg = new TiXmlElement( "timestamp" );
        msg->LinkEndChild( new TiXmlText(toString((int)time_ms.at(i))));
        msgs->LinkEndChild( msg );

        msg= new TiXmlElement( "parameters" );
        msgs->LinkEndChild(  msg );
        TiXmlElement * _params = new TiXmlElement( "textinfo" );
        _params->LinkEndChild(new TiXmlText( text_info.at(i)));
        msg->LinkEndChild( _params );

        msg= new TiXmlElement( "type" );
        msg->LinkEndChild( new TiXmlText("navigation"));
        msgs->LinkEndChild(  msg );
    }


    doc->SaveFile( FileName );
}
string gen_xml::toString(int num)
{
    stringstream abc;
    string value;
    abc<<num;
    value=abc.str();
    return value;
}

int gen_xml::validate(int argc,char* argv[])
{
    fstream filestr;
    string temp;
    bool result;
    if(argc>3)
    {
        cerr<<"Input Arguments Exceeded"<<endl;
        return 0;
    }

    if(validateFileExtention(argv[1],".txt")&&validateFileExtention(argv[2],".xml"))
    {
        filestr.open(argv[1]);

        if (filestr.is_open())
        {
            filestr.close();
            result=true;
        }
        else
        {
            cout << "Error opening file";
            result=false;
        }
    }
    return result;
}
void gen_xml::getData(char* argv[])
{
    fstream filestr;
    string temp;
    filestr.open(argv[1]);
    while( getline( filestr, temp ))
    {
        text_file.push_back( temp );
    }
    //cout<<(int)text_file.at(0).size()<<endl;
    //getAbsoluteTime(text_file.at(0).substr(0,12));

    for(int i=0; i<(int)text_file.size(); i++)
    {
        time_ms.push_back(getAbsoluteTime(text_file.at(i).substr(0,12)));
        temp=text_file.at(i).substr(13,(int)text_file.at(i).size()-14);
        text_info.push_back(temp);
    }
    filestr.close();
}
int gen_xml::getAbsoluteTime(string value)
{
    int hours,minutes,milliseconds;
    int absTime;

    (stringstream)value.substr(3,2)>>hours;
    (stringstream)value.substr(6,2)>>minutes;
    (stringstream)value.substr(9,3)>>milliseconds;
    absTime=60*1000*(hours*60+minutes)+  milliseconds;

    //-- stupid fix for a tool... dont ask why
    tempTime=absTime/1000;
    if(previousTime==tempTime)
    {
        absTime=(tempTime+1)*1000;
    }
    previousTime=tempTime;
    //--
    return absTime;
}
bool gen_xml::validateFileExtention(string name,string ext)
{
    string str (name);
    string str2 (ext);

    size_t found;
    bool res;
    int num_periods = count(name.begin(), name.end(), '.');
    found=str.find(str2);
    if ((found!=string::npos)&&(num_periods==1))
    {
        //cout << "file extention"<<str2<<"found at: " <<int(found) << endl;
        res=true;
    }
    else
    {
        // cout<<"file name incorrect"<<endl;
        res=false;
    }
    return res;
}
void gen_xml::showInput(int argc,char* argv[])
{
    cout<<"argc = "<<argc<<"\t";
    for (int i = 0; i<argc; i++)
    {
        cout<<"argv["<<i<<"] = "<< argv[i]<<"\n";
    }
}


2407
4
задан 1 апреля 2011 в 03:04 Источник Поделиться
Комментарии
1 ответ

Я хотел удалить проверить способ и внести некоторые изменения:

О проверке:


  • Проверить АГДС и argv, которая вне класса, просто укажите имя для метода GetData метод.

  • Вы также должны проверить, когда АГДС меньше 2, пользователь может забыть поставить именем.

  • Открыв файл в метод validate и закрыть его снова, не гарантирует, что он будет еще доступен при вызове метода GetData, так что лучше открывать файл только там и обрабатывать все ошибки там.

О метода GetData:


  • Я бы переименовать его в метод loadData.

  • Для каждой строки загружается вставить значение в time_ms и text_info векторов, называют резерв до петли предварительно выделить необходимый объем памяти.

  • Не нужно звонить близким на поток, он будет рядом, когда его областей конце.

О validateFileExtention:


  • Использовать rfind вместо того, чтобы найти и просто ухватить последнее "." из строки.

  • Вместо этого я хотел создать функцию, чтобы скопировать расширение и проверить оба расширения одновременно, вместо того чтобы найти расширение каждый раз.

  • Я бы даже не заморачивалась расширение на всех. Я бы просто парсер проверяет ее.

О generateXML:


  • Утечка памяти: вы никогда не удаляю док. Также, если вам нужны только внутри метода, почему вы используете динамическую память? Просто создавать его на стеке.

  • Кроме того, проверьте, если tinyxml удаляет все, что можно вставить в документ. Если нет, то придется справиться с этим.

5
ответ дан 1 апреля 2011 в 08:04 Источник Поделиться