1、Qt: QXMLStreamReader,读XML文件实例
效果图:
需求:
打开对应格式的XML文件,读入到QTreewidget树中,并能将XML文件另存为,写入到磁盘。
源码:
main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc,char *argv[]) { QApplication a(argc,argv); MainWindow w; w.show(); return a.exec(); }
XbelReader.h
#ifndef XBELREADER_H #define XBELREADER_H #include <QIcon> #include <QXmlStreamReader> #include <QTreeWidget> #include <QTreeWidgetItem> #include <QIcon> class XbelReader { public: XbelReader(QTreeWidget *tree); bool read(QIODevice *device); QString errorString()const; private: void readXBEL(); void readTitle(QTreeWidgetItem *item); void readSeparator(QTreeWidgetItem *item); void readFolder(QTreeWidgetItem *item); void readBookmark(QTreeWidgetItem *item); QTreeWidgetItem *createChildItem(QTreeWidgetItem *item); private: QXmlStreamReader xml; QTreeWidget *treeWidget; QIcon folderIcon; QIcon bookmarkIcon; }; #endif // XBELREADER_H
XbelReader.cpp
#include <QStyle> #include <QDebug> #include "xbelreader.h" XbelReader::XbelReader(QTreeWidget *tree) { treeWidget = tree; QStyle *style = treeWidget->style(); folderIcon.addPixmap(style->standardPixmap(QStyle::SP_DirClosedIcon),QIcon::Normal,QIcon::Off); folderIcon.addPixmap(style->standardPixmap(QStyle::SP_DirOpenIcon),QIcon::On); bookmarkIcon.addPixmap(style->standardPixmap(QStyle::SP_FileIcon)); } bool XbelReader::read(QIODevice *device) { xml.setDevice(device); if (xml.readNextStartElement()) // { if (xml.name() == "xbel" && xml.attributes().value("version") == "1.0") readXBEL(); else xml.raiseError(QObject::tr("The file is not an XBEL version 1.0 file.")); } return !xml.error(); //非运算,有错返回0,无错返回1 } QString XbelReader::errorString() const { return QObject::tr("%1\nLine %2,column %3") .arg(xml.errorString()) .arg(xml.lineNumber()) .arg(xml.columnNumber()); } void XbelReader::readXBEL() { Q_ASSERT(xml.isStartElement() && xml.name() == "xbel"); while (xml.readNextStartElement()) { if (xml.name() == "folder") readFolder(0); else if (xml.name() == "bookmark") readBookmark(0); else if (xml.name() == "separator") readSeparator(0); else xml.skipCurrentElement(); } } void XbelReader::readTitle(QTreeWidgetItem *item) { Q_ASSERT(xml.isStartElement() && xml.name() == "title"); QString title = xml.readElementText(); item->setText(0,title); } void XbelReader::readSeparator(QTreeWidgetItem *item) { Q_ASSERT(xml.isStartElement() && xml.name() == "separator"); QTreeWidgetItem *separator = createChildItem(item); separator->setFlags(item->flags() & ~Qt::ItemIsSelectable); separator->setText(0,QString(30,0xB7)); xml.skipCurrentElement(); } void XbelReader::readFolder(QTreeWidgetItem *item) { Q_ASSERT(xml.isStartElement() && xml.name() == "folder"); QTreeWidgetItem *folder = createChildItem(item); bool folded = (xml.attributes().value("folded") != "no"); treeWidget->setItemExpanded(folder,!folded); while (xml.readNextStartElement()) { if (xml.name() == "title") readTitle(folder); else if (xml.name() == "folder") readFolder(folder); else if (xml.name() == "bookmark") readBookmark(folder); else if (xml.name() == "separator") readSeparator(folder); else xml.skipCurrentElement(); } } void XbelReader::readBookmark(QTreeWidgetItem *item) { Q_ASSERT(xml.isStartElement() && xml.name() == "bookmark"); QTreeWidgetItem *bookmark = createChildItem(item); bookmark->setFlags(bookmark->flags() | Qt::ItemIsEditable); bookmark->setIcon(0,bookmarkIcon); bookmark->setText(0,QObject::tr("Unknown title")); bookmark->setText(1,xml.attributes().value("href").toString()); while(xml.readNextStartElement()) { if(xml.name() == "title") readTitle(bookmark); else xml.skipCurrentElement(); } } QTreeWidgetItem *XbelReader::createChildItem(QTreeWidgetItem *item) { QTreeWidgetItem *childItem; if (item) { childItem = new QTreeWidgetItem(item); } else { childItem = new QTreeWidgetItem(treeWidget); } childItem->setData(0,Qt::UserRole,xml.name().toString()); return childItem; }
XbelWriter.h
#ifndef XBELWRITER_H #define XBELWRITER_H #include <QXmlStreamWriter> #include <QTreeWidget> #include <QTreeWidgetItem> class XbelWriter { public: XbelWriter(QTreeWidget *tree); bool writeFile(QIODevice *device); private: void writeItem(QTreeWidgetItem *item); QXmlStreamWriter xml; QTreeWidget *treeWidget; }; #endif // XBELWRITER_H
XbelWriter.cpp
#include "xbelwriter.h" XbelWriter::XbelWriter(QTreeWidget *tree) { treeWidget = tree; xml.setAutoFormatting(true); //自动格式化文本 } bool XbelWriter::writeFile(QIODevice *device) { xml.setDevice(device); xml.writeStartDocument(); xml.writeDTD("<!DOCTYPE xbel>"); xml.writeStartElement("xbel"); xml.writeAttribute("version","1.0"); for(int i=0 ; i < treeWidget->topLevelItemCount() ; ++i) writeItem(treeWidget->topLevelItem(i)); xml.writeEndDocument(); return true; } void XbelWriter::writeItem(QTreeWidgetItem *item) { QString tagName = item->data(0,Qt::UserRole).toString(); if(tagName == "folder") { bool folded = !treeWidget->isItemExpanded(item); xml.writeStartElement(tagName); xml.writeAttribute("folded",folded ? "yes" : "no");//三目运算 xml.writeTextElement("title",item->text(0)); for(int i=0 ; i<item->childCount() ; ++i) writeItem(item->child(i)); xml.writeEndElement(); } else if(tagName == "bookmark") { xml.writeStartElement(tagName); if(!item->text(1).isEmpty()) xml.writeAttribute("href",item->text(1)); xml.writeTextElement("title",item->text(0)); xml.writeEndElement(); } else if(tagName == "separator") { xml.writeEmptyElement(tagName); } }原文链接:https://www.f2er.com/xml/294673.html