0

我正在尝试将所有 xml 数据加载到 QList 中。我不确定从 xml 获取所有数据的编码是否正确。

当我尝试运行它时,xml 中的某些信息在输出中丢失了。

以下是xml元素:

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

以下是代码:

检测变量.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;

检测变量.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;
    }

}

数据输出:

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

2 回答 2

0

基于下一个示例:QXmlStreamReader to parse XML in Qt我实现了以下解决方案:

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

要观察 qDebug() 以轻松打印结果,必须实现以下内容:

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;

输出:

(("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"))
于 2020-03-19T04:51:48.533 回答
0

我找到了解决问题的方法。显然这是while循环问题。

解决方法如下:

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

}
于 2020-03-19T06:48:50.187 回答