Search code examples
xmlqtxmlstreamreader

Qt: how to use QtXmlstreamreader to read strings of array data from xml file


I'm trying to load all the xml data into an QList. I'm not sure if I did the right thing of coding of getting all the data from xml.

When I tried to run it, there's some parts of the information from the xml that went missing in the output.

the following is the xml elements:

<?xml version="1.0" encoding="UTF-8"?>
<CANBUS>
  <SYSTEM ID="PCU">


    <CAN ID="veh Ops Status Lights">
      <ID>1</ID>
      <Length>6</Length>
    </CAN>
    <CAN ID="veh Sensors">
      <ID>2</ID>
      <Length>5</Length>
    </CAN>
    <CAN ID="veh Faults">
      <ID>3</ID>
      <Length>5</Length>
    </CAN>
    <CAN ID="PCM Faults">
      <ID>4</ID>
      <Length>2</Length>
    </CAN>
    <CAN ID="faults">
      <ID>5</ID>
      <Length>4</Length>
    </CAN>
    <CAN ID="Fuel level">
      <ID>6</ID>
      <Length>8</Length>
    </CAN>
    <CAN ID="Speed">
      <ID>7</ID>
      <Length>8</Length>
    </CAN>
    <CAN ID="Engine Hr Req">
      <ID>8</ID>
      <Length>8</Length>
    </CAN>
    <CAN ID="Odo and Trip">
      <ID>9</ID>
      <Length>8</Length>
    </CAN>
    <CAN ID="Trip 2">
      <ID>10</ID>
      <Length>8</Length>
    </CAN>
  </SYSTEM>
  <SYSTEM ID="IOU">
    <CAN ID="Sync Counter">
      <ID>11</ID>
      <Length>2</Length>
    </CAN>
    <CAN ID="IOU1 Engine">
      <ID>23</ID>
      <Length>2</Length>
    </CAN>
    <CAN ID="IOU1 Alive">
      <ID>112</ID>
      <Length>8</Length>
    </CAN>
    <CAN ID="IOU1 PCM Fault">
      <ID>20A</ID>
      <Length>2</Length>
    </CAN>
    <CAN ID="IOU1 IOM Fault">
      <ID>40A</ID>
      <Length>4</Length>
    </CAN>
    <CAN ID="IOU1 UNIT Fault">
      <ID>15C</ID>
      <Length>4</Length>
    </CAN>
  </SYSTEM>
</CANBUS>

the following are the codes:

DetectionVar.h

public:
    struct CANList
    {
        QString System;
        QString CAN_ident;
        QString ID;
        QString Length;
    };

    CANList DataCAN;

private:    
    //read the data from file
    QXmlStreamReader xmlReader;
    QString filename;
    QList <CANList> can_identity;

DetectionVar.cpp

void DetectionVar::ReadXML()
{
    filename = QCoreApplication::applicationDirPath() + "/" + "CANBus_Data.xml";
    qDebug() << filename;
    QFile f(filename);
    if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "Cannot read file" << f.errorString();
        return;
    }

    xmlReader.setDevice(&f);

    while(!xmlReader.atEnd())
    {
        xmlReader.readNext();

        if (xmlReader.isStartElement())
        {
            if (xmlReader.name() == "CANBUS")
            {
                while(xmlReader.readNextStartElement())
                {
                    if (xmlReader.name()== "SYSTEM" && xmlReader.attributes().hasAttribute("ID"))
                    {
                        DataCAN.System = xmlReader.attributes().value("ID").toString();
                    }
                    else if (xmlReader.name()== "CAN" && xmlReader.attributes().hasAttribute("ID"))
                    {
                        DataCAN.CAN_ident = xmlReader.attributes().value("ID").toString();
                    }
                    else if (xmlReader.name()== "ID")
                    {
                        DataCAN.ID = xmlReader.readElementText();
                    }
                    else if (xmlReader.name()== "Length")
                    {
                        DataCAN.Length = xmlReader.readElementText();
                    }

                    can_identity.append(DataCAN);
                }
            }
        }
    }

    f.close();


    for (int i = 0; i <can_identity.length(); i++ )
    {
        qDebug()<< "System: " + can_identity.at(i).System;
        qDebug()<< "Ident: " + can_identity.at(i).CAN_ident;
        qDebug()<< "ID: " + can_identity.at(i).ID;
        qDebug()<< "Length: " + can_identity.at(i).Length;
    }

}

output of data:

"System: PCU"
"Ident: "
"ID: "
"Length: "
"System: PCU"
"Ident: veh Ops Status Lights"
"ID: "
"Length: "
"System: PCU"
"Ident: veh Ops Status Lights"
"ID: 1"
"Length: "
"System: PCU"
"Ident: veh Ops Status Lights"
"ID: 1"
"Length: 6"

Solution

  • I have found an solution to the problem. Apparently it's the while loop issue.

    solution is as follows:

    void DetectionVar::ReadXML()
    {
        filename = QCoreApplication::applicationDirPath() + "/" + "CANBus_Data.xml";
        qDebug() << filename;
        QFile f(filename);
        if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            qDebug() << "Cannot read file" << f.errorString();
            return;
        }
    
        xmlReader.setDevice(&f);
    
        while(!xmlReader.atEnd())
        {
            xmlReader.readNext();
    
            if (xmlReader.isStartElement())
            {
                if (xmlReader.name() == "CANBUS")
                {
    
                    while(xmlReader.readNextStartElement())
                    {
                        if (xmlReader.name()== "SYSTEM" && xmlReader.attributes().hasAttribute("ID"))
                        {
                            DataCAN.System = xmlReader.attributes().value("ID").toString();
    
                            while(xmlReader.readNextStartElement())
                            {
                                if (xmlReader.name()== "CAN" && xmlReader.attributes().hasAttribute("ID"))
                                {
                                    DataCAN.CAN_ident = xmlReader.attributes().value("ID").toString();
    
                                    while(xmlReader.readNextStartElement())
                                    {
                                       if (xmlReader.name()== "ID")
                                       {
                                           DataCAN.ID = xmlReader.readElementText();
                                       }
    
                                       else if (xmlReader.name()== "Length")
                                       {
                                           DataCAN.Length = xmlReader.readElementText();
                                       }
                                    }
    
                                    can_identity.append(DataCAN);
                                }
    
                            }
    
                        }
    
                    }
                }
            }
        }
    
        if (xmlReader.hasError())
        {
            qDebug() << "XML Error: " << xmlReader.errorString().data();
        }
    
        f.close();
    
    
        for (int i = 0; i <can_identity.length(); i++ )
        {
            qDebug()<< "System: " + can_identity.at(i).System;
            qDebug()<< "Ident: " + can_identity.at(i).CAN_ident;
            qDebug()<< "ID: " + can_identity.at(i).ID;
            qDebug()<< "Length: " + can_identity.at(i).Length;
        }
    
    }