October 26, 2011

annatz annatz
Lab Rat
37 posts

can’t read a whole xml file

 

hi,

I am trying to read an xml file and I have written the following code :

  1. QFile* file1 = new QFile("c:/anna.xml");
  2.     if (!file1->open(QIODevice::ReadWrite | QIODevice::Text)) {
  3.         QMessageBox::critical(this,
  4.                               "QXSRExample::ReadXMLFile",
  5.                               "Couldn't open anna.xml",
  6.                               QMessageBox::Ok);
  7.         return;
  8.     }
  9.  
  10.     QXmlStreamReader xml(file1);
  11.     while (!xml.atEnd() && !xml.hasError()) {
  12.         if(xml.tokenType() == QXmlStreamReader::StartElement)
  13.              if (xml.name() == "patient_id")
  14.                   chosen_id.insert("id",xml.readElementText());
  15.         xml.readNext();
  16.      }

The xml file is :

  1. <examinations><patient_exams><patient_id>1</patient_id><lab_test><lab_id>Aimo</lab_id><test_id>GENIKI AIMATOS</test_id><specimen>blood</specimen></lab_test></patient_exams></examinations>
  2.  
  3. <examinations><patient_exams><patient_id>6</patient_id><lab_test><lab_id>Mikro</lab_id><test_id>CREA</test_id><specimen>blood</specimen></lab_test></patient_exams></examinations>

The problem is that the program reads only the first two lines from examinations to examinations and not the whole file.
What can i do?

11 replies

October 26, 2011

Franzk Franzk
Lab Rat
830 posts
annatz wrote:
  1. <examinations><patient_exams><patient_id>1</patient_id><lab_test><lab_id>Aimo</lab_id><test_id>GENIKI AIMATOS</test_id><specimen>blood</specimen></lab_test></patient_exams></examinations>
  2.  
  3. <examinations><patient_exams><patient_id>6</patient_id><lab_test><lab_id>Mikro</lab_id><test_id>CREA</test_id><specimen>blood</specimen></lab_test></patient_exams></examinations>

I think you need to put the entire xml document inside an xml tag:

  1. <examination_db>
  2. <examinations><patient_exams><patient_id>1</patient_id><lab_test><lab_id>Aimo</lab_id><test_id>GENIKI AIMATOS</test_id><specimen>blood</specimen></lab_test></patient_exams></examinations>
  3.  
  4. <examinations><patient_exams><patient_id>6</patient_id><lab_test><lab_id>Mikro</lab_id><test_id>CREA</test_id><specimen>blood</specimen></lab_test></patient_exams></examinations>
  5. </examination_db>

Maybe you can’t change the format, but I think you can reduce the text quite a bit:

  1. <examinations>
  2.   <patient_exams patient_id="1">
  3.     <lab_test id="Aimo">
  4.       <test_id>GENIKI AIMATOS</test_id>
  5.       <specimen>blood</specimen>
  6.     </lab_test>
  7.   </patient_exams>
  8.  
  9.   <patient_exams patient_id="6">
  10.     <lab_test id="Mikro">
  11.         <test_id>CREA</test_id>
  12.         <specimen>blood</specimen>
  13.     </lab_test>
  14.   </patient_exams>
  15. </examinations>

The above may be cleaner XML. The changes are all based on assumptions of course, as I don’t know anything about your application. There is even a possibility you can decrease the text clutter even more, increasing the information density and also make your document easier to read and parse.

Ah well.

 Signature 

“Horse sense is the thing a horse has which keeps it from betting on people.”—W.C. Fields

http://www.catb.org/~esr/faqs/smart-questions.html

October 27, 2011

Andre Andre
Area 51 Engineer
6031 posts

FranzK’s tips are excellent. On top of that, I’d like to suggest not to use QFile::ReadWrite file access for only reading the files.

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

October 27, 2011

annatz annatz
Lab Rat
37 posts

i change the xml file myself and make it like frankzk’s and it worked. But i have another problem.
the xml is filled by my code. i have created a function that may be called many times. how can i close the tag <examinations> once?

the function is :

  1. void QXSRExample::CreateXMLFile(){
  2.        QString filename = ("c:/anna.xml");
  3.        QFile file2(filename);
  4.  
  5.         if (!file2.open(QIODevice::Append | QIODevice::Text)){
  6.            QMessageBox::warning(0, "CreateXMLFile", "The file cannot open");}
  7.  
  8.          QXmlStreamWriter* xmlWriter = new QXmlStreamWriter();
  9.          xmlWriter->setDevice(&file2);
  10.  
  11.          xmlWriter->setAutoFormatting(true);
  12.          xmlWriter->writeStartElement("examinations");
  13.          xmlWriter->writeStartElement("patient_exams");
  14.          xmlWriter->writeStartElement("patient_id");
  15.             xmlWriter->writeCharacters (itemId);
  16.          xmlWriter->writeEndElement();
  17. etc...

October 27, 2011

Andre Andre
Area 51 Engineer
6031 posts

We have [developer.qt.nokia.com] been [developer.qt.nokia.com] over [developer.qt.nokia.com] this before, haven’t we annatz?

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

October 27, 2011

annatz annatz
Lab Rat
37 posts

no. the function createxmlfile is call many times and the xml code is created like this:

  1. <examinations>
  2.   <patient_exams patient_id="1">
  3.     <lab_test id="Aimo">
  4.       <test_id>GENIKI AIMATOS</test_id>
  5.       <specimen>blood</specimen>
  6.     </lab_test>
  7.   </patient_exams>
  8. </examinations>
  9.    
  10. <examinations>
  11.   <patient_exams patient_id="6">
  12.     <lab_test id="Mikro">
  13.         <test_id>CREA</test_id>
  14.         <specimen>blood</specimen>
  15.     </lab_test>
  16.   </patient_exams>
  17. </examinations>

and not like this:

  1. <examinations>
  2.   <patient_exams patient_id="1">
  3.     <lab_test id="Aimo">
  4.       <test_id>GENIKI AIMATOS</test_id>
  5.       <specimen>blood</specimen>
  6.     </lab_test>
  7.   </patient_exams>
  8.    
  9.   <patient_exams patient_id="6">
  10.     <lab_test id="Mikro">
  11.         <test_id>CREA</test_id>
  12.         <specimen>blood</specimen>
  13.     </lab_test>
  14.   </patient_exams>
  15. </examinations>

i want all the xml file to be in tag examinations, but when i add more and more data in the file as the function runs many times, i can’t close the tag examinations.

October 27, 2011

Volker Volker
Robot Herder
5428 posts

If you call three times writeStartElement() you should call three times writeEndElement().

October 28, 2011

Andre Andre
Area 51 Engineer
6031 posts

The format doesn’t make much sense to me at all. You need some kind of root element. That could be examinations, but you can also use any other element. But valid XML only has one root element that contains the entire document. I am not suprised that you seem to have trouble making Qt generate a non-valid document, it fits the philosophy of Qt: make it easy to use in the right way, and hard to use in the wrong way.

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

October 28, 2011

KA51O KA51O
Robot Herder
380 posts

you should have a function addExamination(..) that adds all the data for one examination to a list or vector or whatever holding your custom data struct or class. Once you’re done adding examination data, call createXmlFile(..) which creates an Xml file for all the data stored in your exam list.

Of course that’s only one way to do it. But the way you’re doing it at the moment, as you might have noticed, isn’t working.

October 28, 2011

annatz annatz
Lab Rat
37 posts

my problem andre was to create the root element.
thank you both. i will do it in that way ka510

October 28, 2011

Volker Volker
Robot Herder
5428 posts

And do not open the XML file in QIODevice::Append mode unless you cry for ending up with another unreadable file.

October 28, 2011

Andre Andre
Area 51 Engineer
6031 posts

annatz wrote:
my problem andre was to create the root element.
thank you both. i will do it in that way ka510

Sounds obvious to me that if you ask for an element to be created multiple times, then it will be. So, the solution is simply to create the opening tag for the root element once, create all the content, and then create the closing tag for the root element. And ‘once’ here then means: outside your loop writing away your data.

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

 
  ‹‹ QByteArray Remove not working?      [Solved]#123456 to corresponding text ››

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