【问题标题】:Qt: how to use QtXmlstreamreader to read strings of array data from xml fileQt:如何使用 QtXmlstreamreader 从 xml 文件中读取数组数据的字符串
【发布时间】:2020-03-18 10:20:58
【问题描述】:

我正在尝试将所有 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>

以下是代码:

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

}

数据输出:

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

【问题讨论】:

    标签: xml qt xmlstreamreader


    【解决方案1】:

    基于下一个示例: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"))
    

    【讨论】:

      【解决方案2】:

      我找到了解决问题的方法。 显然是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;
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-07
        • 1970-01-01
        • 2019-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多