Can't read a whole xml file



  • hi,

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

    @QFile* file1 = new QFile("c:/anna.xml");
    if (!file1->open(QIODevice::ReadWrite | QIODevice::Text)) {
    QMessageBox::critical(this,
    "QXSRExample::ReadXMLFile",
    "Couldn't open anna.xml",
    QMessageBox::Ok);
    return;
    }

    QXmlStreamReader xml(file1);
    while (!xml.atEnd() && !xml.hasError()) {
        if(xml.tokenType() == QXmlStreamReader::StartElement)
             if (xml.name() == "patient_id")
                  chosen_id.insert("id",xml.readElementText());
        xml.readNext();
     }
    

    @

    The xml file is :

    @<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>

    <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?



  • [quote author="annatz" date="1319653381"]
    @
    <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>

    <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>
    @
    [/quote]

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

    @
    <examination_db>
    <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>

    <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>
    </examination_db>
    @

    Maybe you can't change the format, but I think you can reduce the text quite a bit:
    @
    <examinations>
    <patient_exams patient_id="1">
    <lab_test id="Aimo">
    <test_id>GENIKI AIMATOS</test_id>
    <specimen>blood</specimen>
    </lab_test>
    </patient_exams>

    <patient_exams patient_id="6">
    <lab_test id="Mikro">
    <test_id>CREA</test_id>
    <specimen>blood</specimen>
    </lab_test>
    </patient_exams>
    </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.



  • 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.



  • 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 :
    @void QXSRExample::CreateXMLFile(){
    QString filename = ("c:/anna.xml");
    QFile file2(filename);

        if (!file2.open(QIODevice::Append | QIODevice::Text)){
           QMessageBox::warning(0, "CreateXMLFile", "The file cannot open");}
    
         QXmlStreamWriter* xmlWriter = new QXmlStreamWriter();
         xmlWriter->setDevice(&file2);
    
         xmlWriter->setAutoFormatting(true);
         xmlWriter->writeStartElement("examinations");
         xmlWriter->writeStartElement("patient_exams");
         xmlWriter->writeStartElement("patient_id");
            xmlWriter->writeCharacters (itemId);
         xmlWriter->writeEndElement();
    

    etc...@





  • no. the function createxmlfile is call many times and the xml code is created like this:
    @<examinations>
    <patient_exams patient_id="1">
    <lab_test id="Aimo">
    <test_id>GENIKI AIMATOS</test_id>
    <specimen>blood</specimen>
    </lab_test>
    </patient_exams>
    </examinations>

    <examinations>
    <patient_exams patient_id="6">
    <lab_test id="Mikro">
    <test_id>CREA</test_id>
    <specimen>blood</specimen>
    </lab_test>
    </patient_exams>
    </examinations>@

    and not like this:

    @<examinations>
    <patient_exams patient_id="1">
    <lab_test id="Aimo">
    <test_id>GENIKI AIMATOS</test_id>
    <specimen>blood</specimen>
    </lab_test>
    </patient_exams>

    <patient_exams patient_id="6">
    <lab_test id="Mikro">
    <test_id>CREA</test_id>
    <specimen>blood</specimen>
    </lab_test>
    </patient_exams>
    </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.



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



  • 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.



  • 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.



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



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



  • [quote author="annatz" date="1319793761"]my problem andre was to create the root element.
    thank you both. i will do it in that way ka510[/quote]
    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.