На основе следующего примера: QXmlStreamReader для анализа XML в 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"))