0

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"
0

2 Answers 2

1

Based on the on the next example: QXmlStreamReader to parse XML in Qt I have implemented the following solution:

class CANListParser{
public:
    static QList<CANList> parserXML(QIODevice *device){
        QList<CANList> can_identity;
        QString system;

        QXmlStreamReader xmlReader;
        xmlReader.setDevice(device);

        while(!xmlReader.atEnd() && !xmlReader.hasError()) {
            QXmlStreamReader::TokenType token = xmlReader.readNext();
            if(token == QXmlStreamReader::StartDocument) {
                continue;
            }
            if(token == QXmlStreamReader::StartElement) {
                if(xmlReader.name() == "CANBUS")
                    continue;
                if(xmlReader.name() == "SYSTEM"){
                    system = xmlReader.attributes().value("ID").toString();
                    continue;
                }
                if(xmlReader.name() == "CAN"){
                    CANList c = parseCANList(system, xmlReader);
                    can_identity << c;
                }
            }
        }
        return can_identity;
    }
private:
    static CANList parseCANList(const QString & system, QXmlStreamReader & xmlReader){
        CANList c;
        c.System = system;
        QXmlStreamAttributes attributes = xmlReader.attributes();
        if(attributes.hasAttribute("ID")) {
            c.CAN_ident = attributes.value("ID").toString();
        }
        xmlReader.readNext();
        while(!(xmlReader.tokenType() == QXmlStreamReader::EndElement &&
                xmlReader.name() == "CAN")) {
            if(xmlReader.tokenType() == QXmlStreamReader::StartElement) {
                if(xmlReader.name() == "ID")
                    c.ID = xmlReader.readElementText();
                if(xmlReader.name() == "Length")
                    c.Length = xmlReader.readElementText();
            }
            xmlReader.readNext();
        }
        return c;
    }
};
can_identity << CANListParser::parserXML(&f);

To observe the qDebug() to print the result easily, the following must be implemented:

QDebug operator<<(QDebug debug, const CANList &c){
    QDebugStateSaver saver(debug);
    debug.nospace() << '(' << c.System << ", " << c.CAN_ident << ", " << c.ID << ", " << c.Length << ')';
    return debug;
}
qDebug() << can_identity;

Output:

(("PCU", "veh Ops Status Lights", "1", "6"), ("PCU", "veh Sensors", "2", "5"), ("PCU", "veh Faults", "3", "5"), ("PCU", "PCM Faults", "4", "2"), ("PCU", "faults", "5", "4"), ("PCU", "Fuel level", "6", "8"), ("PCU", "Speed", "7", "8"), ("PCU", "Engine Hr Req", "8", "8"), ("PCU", "Odo and Trip", "9", "8"), ("PCU", "Trip 2", "10", "8"), ("IOU", "Sync Counter", "11", "2"), ("IOU", "IOU1 Engine", "23", "2"), ("IOU", "IOU1 Alive", "112", "8"), ("IOU", "IOU1 PCM Fault", "20A", "2"), ("IOU", "IOU1 IOM Fault", "40A", "4"), ("IOU", "IOU1 UNIT Fault", "15C", "4"))
Sign up to request clarification or add additional context in comments.

Comments

0

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;
    }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.