Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Problem reading an Xml file with QXmlStreamReader
QtWS25 Last Chance

Problem reading an Xml file with QXmlStreamReader

Scheduled Pinned Locked Moved General and Desktop
29 Posts 4 Posters 14.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    annatz
    wrote on last edited by
    #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?

    @void QXSRExample::ReadXMLFile(){
    flag=0;
    QFile* file = new QFile("c:/anna.xml");
    if (!file->open(QIODevice::ReadWrite | QIODevice::Text)) {
    QMessageBox::critical(this,
    "QXSRExample::ReadXMLFile",
    "Couldn't open anna.xml",
    QMessageBox::Ok);
    return;
    }
    QXmlStreamReader xml(file);
    while(!xml.atEnd() ) {
    if(xml.name() == "patient_id") {
    id2=xml.readElementText();
    if (itemId==id2)
    flag=1;}
    xml.readNext();
    }
    xml.clear();
    if (flag==1)
    QMessageBox::warning(this,"Error","O asthenis einai idi kataxwrimenos",QMessageBox::Ok);
    else
    CreateXMLFile();
    file->close();
    }

    void QXSRExample::CreateXMLFile(){
    //Anoigma tou arxeiou
    QString filename = ("c:/anna.xml");
    QFile file2(filename);
    if (!file2.open(QIODevice::Append | QIODevice::Text)){
    //emfanisi sxetikou minimatos gia sfalma
    QMessageBox::warning(0, "Write only", "The file is in write only mode");}
    QXmlStreamWriter* xmlWriter = new QXmlStreamWriter();
    xmlWriter->setDevice(&file2);
    xmlWriter->writeStartElement("examinations");
    xmlWriter->writeStartElement("patient_exams");
    xmlWriter->writeStartElement("patient_id");
    xmlWriter->writeCharacters (itemId);
    xmlWriter->writeEndElement();
    ……………etc
    @

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andre
      wrote on last edited by
      #2

      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?

      1 Reply Last reply
      0
      • A Offline
        A Offline
        annatz
        wrote on last edited by
        #3

        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

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andre
          wrote on last edited by
          #4

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

          @
          void QXSRExample::ReadXMLFile(){
          flag=0;
          QFile* file = new QFile("c:/anna.xml");
          if (!file->open(QIODevice::ReadWrite | QIODevice::Text)) {
          QMessageBox::critical(this,
          "QXSRExample::ReadXMLFile",
          "Couldn't open anna.xml",
          QMessageBox::Ok);
          return;
          }
          QXmlStreamReader xml(file);
          while(!xml.atEnd() ) {
          if(xml.name() == "patient_id") {
          id2=xml.readElementText();
          if (itemId==id2)
          flag=1;
          }
          xml.readNext();
          }
          xml.clear();
          if (flag==1)
          QMessageBox::warning(this,"Error","O asthenis einai idi kataxwrimenos",QMessageBox::Ok);
          else
          CreateXMLFile();
          file->close();
          }
          @

          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.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            annatz
            wrote on last edited by
            #5

            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

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by
              #6

              [quote author="annatz" date="1314113534"]In that way i had done the format of the code.[/quote]
              But that is not what you posted, so not what we could see and study.
              [quote]
              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
              [/quote]

              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.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                annatz
                wrote on last edited by
                #7

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

                @
                <examinations>
                <patient_exams>
                <patient_id>1</patient_id>
                <lab_test>
                <lab_id>Mikro</lab_id>
                <test_id>UREA</test_id>
                <specimen>blood</specimen>
                </lab_test>
                </patient_exams>
                </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

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andre
                  wrote on last edited by
                  #8

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

                  1 Reply Last reply
                  0
                  • L Offline
                    L Offline
                    lgeyer
                    wrote on last edited by
                    #9

                    Have you considered using "QDomDocument":http://doc.qt.nokia.com/latest/qdomdocument.html instead?

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

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #10

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

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        annatz
                        wrote on last edited by
                        #11

                        I change my code like this:

                        @void QXSRExample::ReadXMLFile(){
                        flag=0;
                        QFile* file = new QFile("c:/anna.xml");
                        if (!file->open(QIODevice::ReadWrite | QIODevice::Text)) {
                        QMessageBox::critical(this,
                        "QXSRExample::ReadXMLFile",
                        "Couldn't open anna.xml",
                        QMessageBox::Ok);
                        return;
                        }
                        QXmlStreamReader xml(file);
                        while(!xml.atEnd() && !xml.hasError()){
                        QXmlStreamReader::TokenType token = xml.readNext();
                        if(token == QXmlStreamReader::StartDocument)
                        continue;
                        while(!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "patient_id")) {
                        if(xml.tokenType() == QXmlStreamReader::StartElement) {
                        if(xml.name() == "patient_id") {
                        id2=xml.readElementText();
                        if (itemId==id2)
                        flag=1;
                        }
                        }
                        xml.readNextStartElement();
                        }
                        }
                        xml.clear();
                        if (flag==1)
                        QMessageBox::warning(this,"Error","O asthenis einai idi kataxwrimenos",QMessageBox::Ok);
                        else
                        CreateXMLFile();
                        file->close();
                        }@

                        but now the program craches.

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          andre
                          wrote on last edited by
                          #12

                          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.

                          1 Reply Last reply
                          0
                          • L Offline
                            L Offline
                            lgeyer
                            wrote on last edited by
                            #13

                            [quote author="Andre" date="1314164753"]Yes, but QDomDocument is considdered EOL and is thus not wise to use in new code. [/quote]

                            It is? It is not listed as deprecated in the documentation and the "module maturiy list":http://labs.qt.nokia.com/2011/05/12/qt-modules-maturity-level-the-list/ also states it as done (not deprecated). Is there another source to look at when evaluating module lifetime?

                            1 Reply Last reply
                            0
                            • G Offline
                              G Offline
                              goetz
                              wrote on last edited by
                              #14

                              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.

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

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                andre
                                wrote on last edited by
                                #15

                                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.

                                1 Reply Last reply
                                0
                                • G Offline
                                  G Offline
                                  goetz
                                  wrote on last edited by
                                  #16

                                  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.

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

                                  1 Reply Last reply
                                  0
                                  • A Offline
                                    A Offline
                                    andre
                                    wrote on last edited by
                                    #17

                                    EOL as in: no new features, no real maintenance (only grave bugs might get fixed), and no longer the recommended way to do things. Of course, not as: will be removed. That's how I understood it, at least.

                                    1 Reply Last reply
                                    0
                                    • A Offline
                                      A Offline
                                      annatz
                                      wrote on last edited by
                                      #18

                                      I changed my code.
                                      It doesnt matter that the program will find twice the tag patient_id.
                                      The problem is that in the xml file are the same tags (from examinations to /examinations) many times, and i tried to debug my code and i saw that my code reads the xml (from examinatios to /examinations) only once. it "thinks" that it is the end of the file but it isnt ( it has more tags).

                                      @
                                      while(!xml.atEnd() && !xml.hasError()){
                                      if (xml.name() == "patient_id") {
                                      id2=xml.readElementText();
                                      if (itemId==id2)
                                      flag=1;
                                      }
                                      xml.readNext();
                                      }
                                      @

                                      1 Reply Last reply
                                      0
                                      • A Offline
                                        A Offline
                                        annatz
                                        wrote on last edited by
                                        #19

                                        Hi,

                                        I have created some checkboxes with some examinations.

                                        @checkbox1 = new QCheckBox("Geniki Aimatos", this);
                                        checkbox2 = new QCheckBox("UREA", this);
                                        checkbox3 = new QCheckBox("CREA", this);@

                                        but i want to change my code and read the examinations from an xml file. the xml may change in the future.It may be bigger.
                                        So how can i create the checkboxes? each checkbox should have a different name. if i count the examinations of the file, how can i define the checkboxes?

                                        2 replies
                                        November 7, 2011
                                        Lukas Geyer Lukas Geyer
                                        Gene Splicer
                                        736 posts

                                        Groupie L1
                                        
                                         
                                        |report
                                        

                                        Use QXmlStreamReader to read the XML, create QCheckBoxes on the fly and add them to a layout, for example a QVBoxLayout to have them aligned properly. Use setObjectName() to associate a unique identifier with each checkbox.


                                        I did what you said (Lucas), but can you explain me how to use the setObjectName() please?
                                        i can't find any documentation.

                                        my code is :
                                        QCheckBox* checkbox1=new QCheckBox();
                                        @File* file = new QFile("c:/exetaseis.xml");
                                        if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) {
                                        QMessageBox::critical(this,
                                        "QXSRExample::ok",
                                        "Couldn't open exetaseis.xml",
                                        QMessageBox::Ok);
                                        return;
                                        }

                                        QXmlStreamReader xml(file);
                                        while (!xml.atEnd() && !xml.hasError()) {
                                        if(xml.tokenType() == QXmlStreamReader::StartElement)
                                        if (xml.name() == "lab_test"){
                                        arithmos_exetasewn++;
                                        checkbox1->setObjectName("check");
                                        }
                                        }

                                        xml.readNext();

                                        _layout2->addWidget(checkbox1);
                                        @

                                        Is the way I used the setobjectname correct? and then i should use sth like this
                                        @QList<QCheckBox *> allCheckboxes=checkbox1->findChildren<QCheckBox *>();
                                        @

                                        1 Reply Last reply
                                        0
                                        • G Offline
                                          G Offline
                                          goetz
                                          wrote on last edited by
                                          #20

                                          [quote author="annatz" date="1320921838"]
                                          I did what you said (Lucas), but can you explain me how to use the setObjectName() please?
                                          i can't find any documentation.
                                          [/quote]

                                          Then you did not search properly. Here "it is":http://doc.qt.nokia.com/4.7/qobject.html#objectName-prop

                                          Just as a side note: Use Qt Assistant (it's installed with every Qt) for searching the docs. And you did spot the DOC tab here on DevNet already, didn't you? It has a search function too.

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

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved