Qt中解析xml
2014-11-20 09:31
405 查看
Qt为xml解析提供了三种不同的解析方案:
1、QXmlStreamReader,用于读取格式良好的xml文档的快速解析器;
2、DOM(文档对象模型),将xml文件转换为应用程序可以访问的树形结构;
3、SAX(xml简单应用程序编程接口),通过虚拟函数直接向应用程序报告解析事件。
比较常用的是QXmlStreamReader和DOM,QXmlStreamReader是最简单易行的方法,只需要一个类就可以搞定;DOM是将xml转换为树形结构,然后通过相关的类读取树的各个分支的数据,这种方法用到的类较多,但是功能强大,且解析类型比较多。
本文主要介绍QXmlStreamReader的使用方法,QXmlStreamReader使用简单,但是也存在缺陷,比如它就无法解析XML1.1,但这个问题很好解决。
此类是将xml解析后显示在QTreeWidget中,类可以解析多个文件。
XmlReader::XmlReader(QTreeWidget *treeWidget)
:treeWidget(treeWidget)
{
}
根据读入的文件路径找到文件并打开文件,将文件内容读入到字符串并加入到QXmlStreamReader中。
注意:由于我读入的xml文件是xml1.1格式,QXmlStreamReader无法解析,所以需要将xml文件的第一行换掉,就如程序中注释的那样。
上述两个函数就是对xml进行解析,这里有一个注意点,就是xml.name()返回的是QStringRef,需要转化为QString才能和字符串进行比较。
1、QXmlStreamReader,用于读取格式良好的xml文档的快速解析器;
2、DOM(文档对象模型),将xml文件转换为应用程序可以访问的树形结构;
3、SAX(xml简单应用程序编程接口),通过虚拟函数直接向应用程序报告解析事件。
比较常用的是QXmlStreamReader和DOM,QXmlStreamReader是最简单易行的方法,只需要一个类就可以搞定;DOM是将xml转换为树形结构,然后通过相关的类读取树的各个分支的数据,这种方法用到的类较多,但是功能强大,且解析类型比较多。
本文主要介绍QXmlStreamReader的使用方法,QXmlStreamReader使用简单,但是也存在缺陷,比如它就无法解析XML1.1,但这个问题很好解决。
class XmlReader { public: XmlReader(QTreeWidget *treeWidget); bool readFile(const QStringList fileList); private: void readFileTitle(const QString filename); void readFirstElement(QTreeWidgetItem *parent_item); // 读取不同分支的函数 void readDeviceInfoElement(QTreeWidgetItem *parent_item); void readTripInfoElement(QTreeWidgetItem *parent_item); void readDigStausElement(QTreeWidgetItem *parent_item); void readSetValElement(QTreeWidgetItem *parent_item); void readFaultInfoElement(QTreeWidgetItem *parent_item); void readDataFileSizeElement(QTreeWidgetItem *parent_item); void readFaultKeepingTimeElement(QTreeWidgetItem *parent_item); void readFaultStartTimeElement(QTreeWidgetItem *parent_item); // 跳过未知标签
void skipUnknownElement(); // 创建QTreeWidgetItem
QTreeWidgetItem *createChildItem(QTreeWidgetItem *parent_item=0); QXmlStreamReader xml; QTreeWidget *treeWidget; };
此类是将xml解析后显示在QTreeWidget中,类可以解析多个文件。
XmlReader::XmlReader(QTreeWidget *treeWidget)
:treeWidget(treeWidget)
{
}
bool XmlReader::readFile(const QStringList fileList) { if(fileList.isEmpty()){ std::cerr<<"The file list is emty!"<<std::endl; return false; } int num = fileList.count(); bool isCanRead = false; for(int i=0;i<num;i++){ QString file_str = fileList.at(i); QFile file(file_str); if(!file.open(QFile::ReadOnly | QFile::Text)){ std::cerr<<"Error: Cannot read file "<<qPrintable(file_str) <<": "<<qPrintable(file.errorString())<<std::endl; continue; } //将xml1.1转换为xml1.0 QString str=QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); int lineno = 0; while (!file.atEnd()) { if (lineno) { str += file.readLine(); }else{//跳过第一行 file.readLine(); } lineno++; } xml.clear(); //将读到的文件加入到QXmlStreamReader的输入流中 xml.addData(str); //多个文件中只要有一个文件读取成功,isCanRead置true isCanRead = true; //从文件路径名中提取文件名, QStringList dir=file_str.split("\\"); readFileTitle(dir.last()); file.close(); if(xml.hasError()){ std::cerr<<"Error: Failed to parse file " <<qPrintable(file_str)<<": " <<qPrintable(file.errorString())<<std::endl; // return false; }else if(file.error() != QFile::NoError){ std::cerr<<"Error: Cannot read file " <<qPrintable(file_str)<<": " <<qPrintable(file.errorString())<<std::endl; // return false; } } if(!isCanRead){ std::cerr<<"There is no file can read!"<<std::endl; return false; } return true; }
根据读入的文件路径找到文件并打开文件,将文件内容读入到字符串并加入到QXmlStreamReader中。
注意:由于我读入的xml文件是xml1.1格式,QXmlStreamReader无法解析,所以需要将xml文件的第一行换掉,就如程序中注释的那样。
void XmlReader::readFileTitle(const QString filename) { while(!xml.atEnd()){ if(xml.isStartElement()){ if(xml.name().toString() == "FaultReport"){ QTreeWidgetItem* parent = createChildItem(); parent->setText(0,QObject::tr("FaultReport")); parent->setText(1,filename); readFirstElement(parent); }else{ qDebug()<<"name = "<<xml.name().toString(); qDebug()<<"The Name of element is not FaultReport"; xml.readNext(); } }else{ xml.readNext(); } } }
<pre class="cpp" name="code">void XmlReader::readFirstElement(QTreeWidgetItem *parent_item) { xml.readNext();//跳过<FaultReport> QTreeWidgetItem* devInfo_item = createChildItem(parent_item); devInfo_item->setText(0,QObject::tr("DeviceInfo")); QTreeWidgetItem* tripInfo_item = createChildItem(parent_item); tripInfo_item->setText(0,QObject::tr("TripInfo")); QTreeWidgetItem* digStatus_item = createChildItem(parent_item); digStatus_item->setText(0,QObject::tr("DigitalStatus")); QTreeWidgetItem* setValue_item = createChildItem(parent_item); setValue_item->setText(0,QObject::tr("SettingValue")); QTreeWidgetItem* faultInfo_item = createChildItem(parent_item); faultInfo_item->setText(0,QObject::tr("FaultInfo")); QTreeWidgetItem* dataFileSize_item = createChildItem(parent_item); dataFileSize_item->setText(0,QObject::tr("DataFileSize")); QTreeWidgetItem* faultKeepingTime_item = createChildItem(parent_item); faultKeepingTime_item->setText(0,QObject::tr("FaultKeepingTime")); QTreeWidgetItem* FaultStartTime_item = createChildItem(parent_item); FaultStartTime_item->setText(0,QObject::tr("FaultStartTime")); while(!xml.atEnd()){ if(xml.isEndElement()){//</FaultReport> xml.readNext(); break; } if(xml.isStartElement()){ if(xml.name().toString() == "DeviceInfo"){ readDeviceInfoElement(devInfo_item); }else if(xml.name().toString() == "TripInfo"){ readTripInfoElement(tripInfo_item); }else if(xml.name().toString() == "DigitalStatus"){ readDigStausElement(digStatus_item); }else if(xml.name().toString() == "SettingValue"){ readSetValElement(setValue_item); }else if(xml.name().toString() == "FaultInfo"){ readFaultInfoElement(faultInfo_item); }else if(xml.name().toString() == "DataFileSize"){ readDataFileSizeElement(dataFileSize_item); }else if(xml.name().toString() == "FaultKeepingTime"){ readFaultKeepingTimeElement(faultKeepingTime_item); }else if(xml.name().toString() == "FaultStartTime"){ readFaultStartTimeElement(FaultStartTime_item); }else{ skipUnknownElement(); } }else{ xml.readNext(); } } }
上述两个函数就是对xml进行解析,这里有一个注意点,就是xml.name()返回的是QStringRef,需要转化为QString才能和字符串进行比较。
<p>void XmlReader::readDeviceInfoElement(QTreeWidgetItem *parent_item) { QString name_str,val_str; xml.readNext();</p><p> QTreeWidgetItem* devChild = createChildItem(parent_item);</p><p> while(!xml.atEnd()) { if(xml.isEndElement()){// '/DeviceInfo' xml.readNext(); break; }</p><p> if(xml.isStartElement()){ if(xml.name().toString() == "name"){ // xml.readNext(); name_str = xml.readElementText() 4000 ;</p><p> devChild->setText(0,name_str);</p><p> if(xml.isEndElement()){ xml.readNext(); } }else if(xml.name().toString() == "value"){ val_str = xml.readElementText();</p><p> devChild->setText(1,val_str);</p><p> if(xml.isEndElement()){ xml.readNext(); } }else{ skipUnknownElement(); } }else{ xml.readNext(); } } qDebug()<<"read one device info"; }</p>
其他几个函数都是类似的编程结构,在此就不一一提供了,最后看一下显示效果吧
<img src="https://img-blog.csdn.net/20141120104239812?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbmV3eWhlcg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
相关文章推荐
- qt 解析XML
- qt xml 解析
- qt-xml-生成/解析
- QT开发(四十二)——DOM方式解析XML
- qt4.8.6解析xml
- Qt中使用DOM对XML进行的各种解析(总结) 转
- Qt开发:DOM解析xml实现读、写、增、删、改
- Qt之解析XML元素(QXmlStreamReader)
- Qt之解析XML(QXmlStreamReader)
- qt 之解析XML元素(QXmlStreamReader)
- QT中使用QXmlStreamReader解析XML文件
- 基于Qt的xml解析
- QT中使用QXmlStreamReader解析XML文件
- QT5下vs2013中利用tinyXML解析XML文件
- Qt XML数据解析
- Qt解析xml
- Qt 解析XML文件
- Qt浅谈之二十八解析XML文件
- QT开发(四十四)——流方法解析XML
- QT读写XML文件之DOM方式解析XML