[Solved] QXmlStreamWriter: insert an element before the already written end of document ?
-
Hello,
I am working on a trace component within a library that is then use by an application. This application calls at the beginning an 'openTrace("my_trace.xml")' method, then regularly trace("something to trace", ...), and at the end of its life calls a closeTrace().
@//pseudo code illustration
int main(...)
{
// open the trace file
openTrace( "my_trace.xml" );// Application writes things in the file during its life // using trace trace( "msg_type", "msg_text" ) // close the file at the end closeTrace(); return 0;
}@
The current implementation is using a QXmlStreamWriter. It is fine for us so far.
@
// The openTrace method
{
m_file.open(QIODevice::WriteOnly | QIODevice::Text);
m_xmlStreamWriter.setDevice(&m_file);
m_xmlStreamWriter.writeStartDocument();
m_xmlStreamWriter.writeDTD("<!DOCTYPE APP_TRACE>");
m_xmlStreamWriter.writeStartElement("app_trace");
}// The trace method
{
m_xmlStreamWriter.writeStartElement("trace");m_xmlStreamWriter.writeTextElement("prefix" , p_prefix ); m_xmlStreamWriter.writeTextElement("date" , strDateTime ); m_xmlStreamWriter.writeTextElement("frame" , QString("%1").arg(m_currentFrame) ); m_xmlStreamWriter.writeTextElement("message", p_message); m_xmlStreamWriter.writeEndElement(); // flush so the all new element entry is written (for consistency of the element) m_file.flush();
}
// The close method
{
m_xmlStreamWriter.writeEndDocument();
m_file.close();
}
@Now, I am trying to fix a bug: when the application crashes (for example), my file "my_trace.xml" is not "consistent", i.e. since the 'close' has not been called, the
@m_xmlStreamWriter.writeEndDocument();@
has not been called (not surprising!), so I am missing the closing statement </app_trace>In order to fix this bug, I am thinking of something like: I write the end of the document right away on opening and then when writing a new element I "just" have to insert it before the 'ending' statement. But it seems not to work that way. I have not found a way to do that, yet.
Also it looks like to have a consistent file at any time during the application life, I should use QDom, but I have read that it is not as efficient as QXmlStreamWriter (my source: C++ Gui Programming with Qt4), and by a glance at it, I am not tempted at rewriting the file each time I add a new element! because my file may become quite large (12 meg or even more!).So my question is:
Is it possible to go backward just one line in a QXmlStreamWriter in order to "insert" an element? Something I missed in the doc or examples?On a final thought, I guess I am looking for a compromise between efficiency and consistency !?.
Any suggestions / insights will be welcomed.
Cheers
-
[quote author="Archer2005" date="1318426338"]Is it possible to go backward just one line in a QXmlStreamWriter in order to "insert" an element? Something I missed in the doc or examples?[/quote]
No. QDomDocument won't help you either as it keeps the document in memory - if your application crashes your document is gone too.
There is no guarantee that you can run any code after an unhandled exception ("crash"). You might try to install an unhandled exception handler which "closes" the XML file first and then gracefully shuts down the application.
Is there any good reason XML is used in the first place? It might be a bad choice after all as it requires to run code "after it happened" to produce valid output (in contrast to a plain text file for example).
If you absolutely require valid XML even after a crash I see no other way the going for an external process which receives trace outputs from your application through some sort of IPC and writes out the XML.
However, I would probably go for a relaxing parser instead, which treats XML files missing an closing element as valid.
-
Thanks for the reply.
[quote author="Lukas Geyer" date="1318431343"]No. QDomDocument won't help you either as it keeps the document in memory - if your application crashes your document is gone too.[/quote]
Ok, thanks for the confirmation on this.[quote author="Lukas Geyer" date="1318431343"]There is no guarantee that you can run any code after an unhandled exception ("crash"). You might try to install an unhandled exception handler which "closes" the XML file first and then gracefully shuts down the application.
Is there any good reason XML is used in the first place? It might be a bad choice after all as it requires to run code "after it happened" to produce valid output (in contrast to a plain text file for example).
If you absolutely require valid XML even after a crash I see no other way the going for an external process which receives trace outputs from your application through some sort of IPC and writes out the XML.[/quote]
I agree with what you are saying. The choice of XML formatting was just for post treatment 'easyness'.[quote author="Lukas Geyer" date="1318431343"]However, I would probably go for a relaxing parser instead, which treats XML files missing an closing element as valid.[/quote]
Thanks, point taken! -
Well, my suggestion is to actually fix the crash.
Crashes are going to leave your application in an inconsistent state, no matter what you do. Your best bet is therefore to prevent them, and to handle exceptions gracefully if possible at all. One measure you could take if you have to use external code that is phrone to crash, is to isolate that piece into a separate process.
-
@Andre :
Yes of course, it is an evidence (to fix any crashes)! I completely agree with you.
But the crash I was talking about was introduced on purpose in the application to test/verify the behavior of the xml trace writer in such harsh condition (I stated "for example" in my original post - Sorry, I should have been a lot more explicit on this point).