#ifndef SIM_XMLSTREAMREADER_H_ #define SIM_XMLSTREAMREADER_H_#include <QString> #include <QXmlStreamReader>class XmlStreamReader { public:XmlStreamReader();~XmlStreamReader();//读取文件bool ReadFile(const QString &fileName);//跳过不能识别的元素void SkipUnknownElement();//读取XML文件的主体部分void ReadWantDecideEditElement();//解析想定基本信息void ReadScenarioElement();//解析想定文件实体信息void ReadEntitiesElement();//解析想定文件模型发布订阅关系void ReadModelsElement();//解析该实体的所有参数void ReadParametersElement();//解析发布关系void ReadPublishElement();//解析订阅关系void ReadSubscribeElement();private:QXmlStreamReader m_qxml_reader; };#endif //SIM_XMLSTREAMREADER_H_
#include "xml_stream_reader.h" #include <QFile> #include <QDebug> #include <iostream> using namespace std;XmlStreamReader::XmlStreamReader() {}XmlStreamReader::~XmlStreamReader() { }bool XmlStreamReader::ReadFile(const QString &fileName) {QFile file(fileName);if (!file.open(QFile::ReadOnly | QFile::Text)) {std::cerr << "Error: Cannot read file " << qPrintable(fileName)<< ": " << qPrintable(file.errorString())<< std::endl;return false;}//如果文件打开成功,将它设置为QXmlStreamReader的输入设备m_qxml_reader.setDevice(&file);//readNext()函数从输入流中读取下一个记号,如果成功而且还没有到达XML文件的结尾,函数将进入while循环,//每次调用readNext()函数,下一个记号就会被读取并变成当前的记号,readNext()函数报告error,atEnd返回true m_qxml_reader.readNext(); //当读取到XML文档结尾,或者发生错误,atEnd()函数返回truewhile (!m_qxml_reader.atEnd()) {//如果当前记号为StartElement,返回trueif (m_qxml_reader.isStartElement()){if (m_qxml_reader.name() == "WantDecideEdit") {ReadWantDecideEditElement();}else {m_qxml_reader.raiseError(QObject::tr("Not a WantDecideEdit file"));}}else {m_qxml_reader.readNext();}}file.close();if (m_qxml_reader.hasError()){std::cerr << "Error: Failed to parse file "<< qPrintable(fileName) << ": "<< qPrintable(m_qxml_reader.errorString()) << std::endl;return false;}else if (file.error() != QFile::NoError) {std::cerr << "Error: Cannot read file " << qPrintable(fileName)<< ": " << qPrintable(file.errorString())<< std::endl;return false;}return true; }void XmlStreamReader::ReadWantDecideEditElement() {//跳过当前记号,只可能是WantDecideEdit记号 m_qxml_reader.readNext();while (!m_qxml_reader.atEnd()) {//如果读取到关闭标签,只能是</WantDecideEdit>记号,跳过这个标签并跳出循环if (m_qxml_reader.isEndElement()){if (m_qxml_reader.name() == "WantDecideEdit"){m_qxml_reader.readNext();break;}elsem_qxml_reader.readNext();}if (m_qxml_reader.isStartElement()){if (m_qxml_reader.name() == "ScenarioInfo"){ReadScenarioElement();}else if (m_qxml_reader.name() == "Entities"){ReadEntitiesElement();}else if (m_qxml_reader.name() == "Models"){ReadModelsElement();}else{SkipUnknownElement();}}else{m_qxml_reader.readNext();}} }void XmlStreamReader::ReadScenarioElement() {m_qxml_reader.readNext();while (!m_qxml_reader.atEnd()) {if (m_qxml_reader.isEndElement()) {if (m_qxml_reader.name() == "ScenarioInfo"){m_qxml_reader.readNext();break;}elsem_qxml_reader.readNext();}if (m_qxml_reader.isStartElement()) {if (m_qxml_reader.name() == "Name"){QString name = m_qxml_reader.readElementText();qDebug() << "name:" << name << endl;}else if (m_qxml_reader.name() == "ModificationDate"){QString modification_date = m_qxml_reader.readElementText();qDebug() << "modification_date:" << modification_date << endl;}else if (m_qxml_reader.name() == "Description"){QString description = m_qxml_reader.readElementText();qDebug() << "description:" << description << endl;return;}else {SkipUnknownElement();}}else {m_qxml_reader.readNext();}} }void XmlStreamReader::ReadParametersElement() {m_qxml_reader.readNext();while (!m_qxml_reader.atEnd()){if (m_qxml_reader.isEndElement()){if (m_qxml_reader.name() == "Parameters"){m_qxml_reader.readNext();break;}elsem_qxml_reader.readNext();}if (m_qxml_reader.isStartElement()){if (m_qxml_reader.name() == "Parameter"){QString name = m_qxml_reader.attributes().value("name").toString();QString type = m_qxml_reader.attributes().value("type").toString();QString display_name = m_qxml_reader.attributes().value("displayName").toString();QString usage = m_qxml_reader.attributes().value("usage").toString();QString value = m_qxml_reader.attributes().value("value").toString();qDebug() << "name:" << name << " " << "type:" << type << " " << "display_name:" << display_name << " " << "usage:" << usage << " " << "value:" << value << endl;m_qxml_reader.readNext();}else{SkipUnknownElement();}}else{m_qxml_reader.readNext();}} }void XmlStreamReader::ReadPublishElement() {m_qxml_reader.readNext();while (!m_qxml_reader.atEnd()){if (m_qxml_reader.isEndElement()){if (m_qxml_reader.name() == "Publish"){m_qxml_reader.readNext();break;}elsem_qxml_reader.readNext();}if (m_qxml_reader.isStartElement()){if (m_qxml_reader.name() == "Topic"){QString topic_name = m_qxml_reader.attributes().value("topicName").toString();QString topic_param_name = m_qxml_reader.attributes().value("topicParamName").toString();QString model_param_name = m_qxml_reader.attributes().value("modelParamName").toString();qDebug() << "topicName:" << topic_name << ",topicParamName:" << topic_param_name << ",modelParamName:" << model_param_name << endl;m_qxml_reader.readNext();}else{SkipUnknownElement();}}else{m_qxml_reader.readNext();}} }void XmlStreamReader::ReadSubscribeElement() {m_qxml_reader.readNext();while (!m_qxml_reader.atEnd()){if (m_qxml_reader.isEndElement()){if (m_qxml_reader.name() == "Subscribe"){m_qxml_reader.readNext();break;}elsem_qxml_reader.readNext();}if (m_qxml_reader.isStartElement()){if (m_qxml_reader.name() == "Topic"){QString topic_name = m_qxml_reader.attributes().value("topicName").toString();QString topic_param_name = m_qxml_reader.attributes().value("topicParamName").toString();QString model_param_name = m_qxml_reader.attributes().value("modelParamName").toString();qDebug() << "topicName:" << topic_name << ",topicParamName:" << topic_param_name << ",modelParamName:" << model_param_name << endl;m_qxml_reader.readNext();}else{SkipUnknownElement();}}else{m_qxml_reader.readNext();}} }void XmlStreamReader::ReadEntitiesElement() {m_qxml_reader.readNext();while (!m_qxml_reader.atEnd()) {if (m_qxml_reader.isEndElement()) {if (m_qxml_reader.name() == "Entities"){m_qxml_reader.readNext();break;}elsem_qxml_reader.readNext();}if (m_qxml_reader.isStartElement()) {if (m_qxml_reader.name() == "Entity"){QString object_handle = m_qxml_reader.attributes().value("objectHandle").toString();qDebug() << "objectHandle:" << object_handle << endl;QString model_uuid = m_qxml_reader.attributes().value("modelUUID").toString();qDebug() << "modelUUID:" << model_uuid<<endl;m_qxml_reader.readNext();}else if (m_qxml_reader.name() == "Parameters"){ReadParametersElement();}else {SkipUnknownElement();}}else {m_qxml_reader.readNext();}} }void XmlStreamReader::ReadModelsElement() {m_qxml_reader.readNext();while (!m_qxml_reader.atEnd()) {if (m_qxml_reader.isEndElement()) {if (m_qxml_reader.name() == "Models"){m_qxml_reader.readNext();break;}elsem_qxml_reader.readNext();}if (m_qxml_reader.isStartElement()) {if (m_qxml_reader.name() == "Model"){QString model_uuid = m_qxml_reader.attributes().value("modelUUID").toString();qDebug() << "modelUUID:" << model_uuid<<endl;m_qxml_reader.readNext();}else if (m_qxml_reader.name() == "Publish"){ReadPublishElement();}else if (m_qxml_reader.name() == "Subscribe"){ReadSubscribeElement();}else {SkipUnknownElement();}}else {m_qxml_reader.readNext();}} } void XmlStreamReader::SkipUnknownElement() {m_qxml_reader.readNext();while (!m_qxml_reader.atEnd()) {if (m_qxml_reader.isEndElement()) {m_qxml_reader.readNext();break;}if (m_qxml_reader.isStartElement()) {SkipUnknownElement();}else {m_qxml_reader.readNext();}} }
void writeIndexEntry(QXmlStreamWriter *xmlWriter, QTreeWidgetItem *item) {xmlWriter->writeStartElement("entry");xmlWriter->writeAttribute("term", item->text(0));QString pageString = item->text(1);if (!pageString.isEmpty()){QStringList pages = pageString.split(", ");foreach(QString page, pages)xmlWriter->writeTextElement("page", page);}for (int i = 0; i < item->childCount(); ++i)writeIndexEntry(xmlWriter, item->child(i));xmlWriter->writeEndElement(); }bool WriteXml(const QString &fileName, QTreeWidget *treeWidget) {QFile file(fileName);if (!file.open(QFile::WriteOnly | QFile::Text)) {std::cerr << "Error: Cannot write file "<< qPrintable(fileName) << ": "<< qPrintable(file.errorString()) << std::endl;return false;}QXmlStreamWriter xmlWriter(&file);//开启自动格式编辑功能,XML文档将以更友好易读的格式输出,在每一行都有明确显示数据递归结构的缩进xmlWriter.setAutoFormatting(true);//在XML文档首行写"<?xml version="1.0" encoding="UTF-8"?>" xmlWriter.writeStartDocument();xmlWriter.writeStartElement("WantDecideEdit");for (int i = 0; i < treeWidget->topLevelItemCount(); ++i)writeIndexEntry(&xmlWriter, treeWidget->topLevelItem(i));xmlWriter.writeEndDocument();file.close();if (file.error()){std::cerr << "Error: Cannot write file "<< qPrintable(fileName) << ": "<< qPrintable(file.errorString()) << std::endl;return false;}return true; }