August 23, 2011

annatz annatz
Lab Rat
37 posts

Problem reading an Xml file with QXmlStreamReader

Page  
1

Ηi,
The code that follows reads a file and if a patient already exists, shows an error message, otherwise it calls the function
CreateXMLFile. The problem is that it gets in the while loop only once and the value of the id2 is always the same.
What can i do?

  1. void QXSRExample::ReadXMLFile(){
  2.     flag=0;
  3.     QFile* file = new QFile("c:/anna.xml");
  4.     if (!file->open(QIODevice::ReadWrite | QIODevice::Text)) {
  5.         QMessageBox::critical(this,
  6.                                  "QXSRExample::ReadXMLFile",
  7.                                  "Couldn't open anna.xml",
  8.                                  QMessageBox::Ok);
  9.         return;
  10.        }
  11.      QXmlStreamReader xml(file);
  12.      while(!xml.atEnd() ) {
  13.       if(xml.name() == "patient_id") {
  14.           id2=xml.readElementText();
  15.           if (itemId==id2)
  16.               flag=1;}
  17.          xml.readNext();
  18.    }
  19.      xml.clear();
  20.          if (flag==1)
  21.              QMessageBox::warning(this,"Error","O asthenis einai idi kataxwrimenos",QMessageBox::Ok);
  22.          else
  23.              CreateXMLFile();
  24.          file->close();
  25. }
  26.  
  27. void QXSRExample::CreateXMLFile(){
  28.     //Anoigma tou arxeiou
  29.        QString filename = ("c:/anna.xml");
  30.        QFile file2(filename);
  31.         if (!file2.open(QIODevice::Append | QIODevice::Text)){
  32.          //emfanisi sxetikou minimatos gia sfalma
  33.            QMessageBox::warning(0, "Write only", "The file is in write only mode");}
  34.          QXmlStreamWriter* xmlWriter = new QXmlStreamWriter();
  35.          xmlWriter->setDevice(&file2);
  36.          xmlWriter->writeStartElement("examinations");
  37.          xmlWriter->writeStartElement("patient_exams");
  38.          xmlWriter->writeStartElement("patient_id");
  39.             xmlWriter->writeCharacters (itemId);
  40.          xmlWriter->writeEndElement();
  41. ……………etc

28 replies

August 23, 2011

Andre Andre
Robot Herder
6394 posts

Please, reformat your code to use proper, consistent indenting. That will make it much easier to spot the issue you are running into.

I really don’t get the logic of starting to write an XML file while trying to read that same file. How is that supposed to work?

August 23, 2011

annatz annatz
Lab Rat
37 posts

first i read the file to see if there is a patient with the same id. if there isn’t a patient with that id i write to the file the examinations for that patient.

i don’t understand how to make my code

August 23, 2011

Andre Andre
Robot Herder
6394 posts

I mean a formatting like below, makes your code more readable and thus makes it easier to spot what is going wrong.

  1. void QXSRExample::ReadXMLFile(){
  2.     flag=0;
  3.     QFile* file = new QFile("c:/anna.xml");
  4.     if (!file->open(QIODevice::ReadWrite | QIODevice::Text)) {
  5.         QMessageBox::critical(this,
  6.                               "QXSRExample::ReadXMLFile",
  7.                               "Couldn't open anna.xml",
  8.                               QMessageBox::Ok);
  9.         return;
  10.     }
  11.     QXmlStreamReader xml(file);
  12.     while(!xml.atEnd() ) {
  13.         if(xml.name() == "patient_id") {
  14.             id2=xml.readElementText();
  15.             if (itemId==id2)
  16.                 flag=1;
  17.         }
  18.         xml.readNext();
  19.     }
  20.     xml.clear();
  21.     if (flag==1)
  22.         QMessageBox::warning(this,"Error","O asthenis einai idi kataxwrimenos",QMessageBox::Ok);
  23.     else
  24.         CreateXMLFile();
  25.     file->close();
  26. }

I don’t think it is a good idea to try to write to a file from the function that is supposed to read from it. IMHO, it is better to separate that into different functions, and don’t call the one from the other.

August 23, 2011

annatz annatz
Lab Rat
37 posts

In that way i had done the format of the code.

ok, i will seperate the two functions but you didnt response to my problem.

The problem is that it gets in the while loop only once and the value of the id2 is always the same.
it doesnt read the next patient_id

August 23, 2011

Andre Andre
Robot Herder
6394 posts

annatz wrote:
In that way i had done the format of the code.

But that is not what you posted, so not what we could see and study.

ok, i will seperate the two functions but you didnt response to my problem.

The problem is that it gets in the while loop only once and the value of the id2 is always the same.
it doesnt read the next patient_id

Could you post the XML that you are trying to read then? We can not check if the code is at fault in this case.

August 23, 2011

annatz annatz
Lab Rat
37 posts

i write the xml but at the preview it is different.

  1. <examinations>
  2.   <patient_exams>
  3.     <patient_id>1</patient_id>
  4.     <lab_test>
  5.       <lab_id>Mikro</lab_id>
  6.       <test_id>UREA</test_id>
  7.       <specimen>blood</specimen>
  8.     </lab_test>
  9.   </patient_exams>
  10. </examinations>

the number 1 that is after examinations is after patient_id. and after examinations is the tag patient_exams

Edit: reformatted XML to make it more readable. Please do that yourself next time; Andre

August 23, 2011

Andre Andre
Robot Herder
6394 posts

With the above piece of XML, and the code that you showed, you will encounter the patient_id tag twice: once for the openening, and once for the closing tag. id2 will contain the text “1” on the first call, and be empty for the second (read the docs on readElementText for an explanation why).

It is obviously always the same, because the XML does not change all of a sudden during the reading (that is: you should not change the XML, as I told you before).

August 23, 2011

Lukas Geyer Lukas Geyer
Lab Rat
2074 posts

Have you considered using QDomDocument [doc.qt.nokia.com] instead?

This will create an in-memory representation of your XML document which allows for searching and inserting / removing nodes.

August 24, 2011

Andre Andre
Robot Herder
6394 posts

Yes, but QDomDocument is considdered EOL and is thus not wise to use in new code.

August 24, 2011

annatz annatz
Lab Rat
37 posts

I change my code like this:

  1. void QXSRExample::ReadXMLFile(){
  2.     flag=0;
  3.     QFile* file = new QFile("c:/anna.xml");
  4.     if (!file->open(QIODevice::ReadWrite | QIODevice::Text)) {
  5.         QMessageBox::critical(this,
  6.                                  "QXSRExample::ReadXMLFile",
  7.                                  "Couldn't open anna.xml",
  8.                                  QMessageBox::Ok);
  9.         return;
  10.        }
  11.      QXmlStreamReader xml(file);
  12.      while(!xml.atEnd() && !xml.hasError()){
  13.           QXmlStreamReader::TokenType token = xml.readNext();
  14.              if(token == QXmlStreamReader::StartDocument)
  15.               continue;      
  16.       while(!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "patient_id")) {
  17.           if(xml.tokenType() == QXmlStreamReader::StartElement) {
  18.               if(xml.name() == "patient_id") {
  19.                 id2=xml.readElementText();
  20.                 if (itemId==id2)
  21.                 flag=1;
  22.                }
  23.           }
  24.           xml.readNextStartElement();
  25.       }
  26.   }
  27.      xml.clear();
  28.          if (flag==1)
  29.              QMessageBox::warning(this,"Error","O asthenis einai idi kataxwrimenos",QMessageBox::Ok);
  30.          else
  31.              CreateXMLFile();
  32.          file->close();
  33. }

but now the program craches.

August 24, 2011

Andre Andre
Robot Herder
6394 posts

Again: please make your code easy to read here. Take care of indentation and the likes.

Then, your code looks like nonsense. First you iterate through the whole XML in search of a StartDocument tag, and then you do nothing with it. Then, you expect there is more to read?
A crash is easy to debug usually. Your debugger will tell what line triggered the crash.

August 24, 2011

Lukas Geyer Lukas Geyer
Lab Rat
2074 posts
Andre wrote:
Yes, but QDomDocument is considdered EOL and is thus not wise to use in new code.

It is? It is not listed as deprecated in the documentation and the module maturiy list [labs.qt.nokia.com] also states it as done (not deprecated). Is there another source to look at when evaluating module lifetime?

August 24, 2011

Volker Volker
Ant Farmer
5428 posts

XML DOM should never be EOL. It is the only means to manipulate an XML document in-memory. And sometimes there are cases where you just plain cannot use a stream writer, e.g. when you need to add nodes at two different places in the tree simultaneously.

August 24, 2011

Andre Andre
Robot Herder
6394 posts

Let me put it this way: if I am wrong, then Thiago was wrong. He’s the one saying something along these lines, but I can not remember if it was on IRC or on the mailinglist.

August 24, 2011

Volker Volker
Ant Farmer
5428 posts

Maybe it’s EOL in the sense of “no new features”. But there’s far too much code out there that relies on QDom. One should consider the stream classes for new projects, though.

Page  
1

  ‹‹ Translate the result of QLocale::languageToString()      sending a signal to my mainwindow ››

You must log in to post a reply. Not a member yet? Register here!