Search code examples
c++qttextqdomdocument

Better way to use QDomDocument data as text


I am a newbie, I am creating a XML file in which I need to give CRC value to cross check on server. For this I need QDomDocument data as text. For this I am first creating XML file with fake CRC value. Then I open it with QFile and read all data. Then I split data and calculate data CRC. Now I have to rewrite whole file again. I know it is the worst idea ever to write same file twice but as I am a newbie, I don't know how to do it in better style. Here is my code:-

QDomElement docElem = doc.documentElement();
QFile xmlfile(filename);
if(!xmlfile.open(QIODevice::ReadWrite | QIODevice::Text))
{
    qDebug("Can not open file device.");
}
xmlfile.resize(0);
QXmlStreamWriter xw;
xw.setDevice(&xmlfile);      //set file to XML writer
xw.setAutoFormatting(true);
xw.setAutoFormattingIndent(4);
xw.writeStartDocument();
xw.writeStartElement(fileID); //fileID as the start element
if(docElem.hasAttributes())
{
    xw.writeAttribute("xmlns:xs",docElem.attribute("xmlns:xs"));
    xw.writeAttribute("xmlns",docElem.attribute("xmlns"));
}

xw.writeTextElement("Frame_Start_ID","STX");
xw.writeTextElement("Frame_Length","1234");
xw.writeTextElement("Source_Device_Id","CDIS_PIS ");
xw.writeTextElement("Destination_Device_Id","DDNS-SERVER ");
xw.writeTextElement("Frame_Code","I");
xw.writeStartElement("Frame_Data");
//inside frame data
xw.writeTextElement("File_Number","1");
xw.writeTextElement("File_Name","Event");

for(int j=0;j<logFields.count();j++)
{
    xw.writeTextElement(logFields.at(j),logData.at(j));
}
xw.writeEndElement();
xw.writeTextElement("CRC","14405904");
xw.writeTextElement("Frame_End_Id","ETX");
xw.writeEndDocument();
xmlfile.flush();
xmlfile.close();



   QFile xmlfyle(filename);

    xmlfyle.open(QIODevice::ReadWrite | QIODevice::Text);
    QString content = (QString)xmlfyle.readAll();
    QStringList list1 = content.split("<CRC>");

    qDebug() << "Split value = " << list1.at(0);
    QByteArray crc_new = crc_o.crc_generate_modbus((unsigned char*)list1.at(0).data(),list1.at(0).size());
    xmlfyle.resize(0);
    QXmlStreamWriter xw_new;
    xw_new.setDevice(&xmlfyle);      //set file to XML writer
    xw_new.setAutoFormatting(true);
    xw_new.setAutoFormattingIndent(4);
    xw_new.writeStartDocument();
    xw_new.writeStartElement(fileID); //fileID as the start element

     if(docElem.hasAttributes())
    {
        xw_new.writeAttribute("xmlns:xs",docElem.attribute("xmlns:xs"));
        xw_new.writeAttribute("xmlns",docElem.attribute("xmlns"));
    }

    xw_new.writeTextElement("Frame_Start_ID","STX");
    xw_new.writeTextElement("Frame_Length","1234");
    xw_new.writeTextElement("Source_Device_Id","CDIS_PIS ");
    xw_new.writeTextElement("Destination_Device_Id","DDNS-SERVER ");
    xw_new.writeTextElement("Frame_Code","I");
    xw_new.writeStartElement("Frame_Data");
    xw_new.writeTextElement("File_Number","1");
    xw_new.writeTextElement("File_Name","Event");
    for(int j=0;j<logFields.count();j++)
    {
        xw_new.writeTextElement(logFields.at(j),logData.at(j));
    }
    xw_new.writeEndElement();
    char tab[10];
    sprintf(tab,"%d",crc_new.data());
    xw_new.writeTextElement("CRC",QString::fromUtf8(tab));
    xw_new.writeTextElement("Frame_End_Id","ETX");
    xw_new.writeEndDocument();
    xmlfyle.flush();
    xmlfyle.close();

can anyone suggest me what could be a better way to do this.Thanks


Solution

  • One version of QXmlStreamWriter constructor accepts a QByteArray and writes into the array instead of an output file.

    QXmlStreamWriter Class

    So what you can do is; using QXmlStreamWriter, prepare data for your XML in a QByteArray, do whatever you need to do with the CRC inside this data; and when everything is done, write this QByteArray to the output file.