来源https://www.devbean.net/2013/07/qt-study-road-2-read-xml-with-stream/ 建立XML文档
<bookindex> <entry term="sidebearings"> <page>10</page> <page>34-35</page> <page>307-308</page> </entry> <entry term="subtraction"> <entry term="of pictures"> <page>115</page> <page>244</page> </entry> <entry term="of vectors"> <page>9</page> </entry> </entry> </bookindex>在Pro文件中声明XML
QT += core gui xml头文件
public: MainWindow(QWidget *parent = 0); ~MainWindow(); //读取file bool readFile(const QString &fileName); private: //读取截点 //父节点 //子节点(QTreeWidgetItem *parent) //读取bookindex节点 void readBookindexElement(); //读取entry节点 void readEntryElement(QTreeWidgetItem *parent); //读取page节点 void readPageElement(QTreeWidgetItem *parent); //无关节点跳过 void skipUnknownElement(); QTreeWidget *treeWidget; QXmlStreamReader reader;方法依次为: 1.读取文件 2.读取父节点bookindex 3.读取子节点entry(接受传过来的父节点 bookindex) 4.读取子节点page(接受传过来的父节点 entry) 5.跳过无关节点 读取文件:
bool MainWindow::readFile(const QString &fileName) { QFile file(fileName); if(!file.open(QFile::ReadOnly | QFile::Text)){ QMessageBox::information(this,tr("open error"),tr("connot read file %1").arg(fileName)); qDebug()<<"error"; return false; } qDebug()<<QDir::currentPath(); //将file设置为QXmlStreamReader的设备(Stream从file中读取内容) //Sets the current device to device. //Setting the device resets the stream to its initial state. reader.setDevice(&file); //判断文件是否读到末尾 while(!reader.atEnd()){ //判断是否是开始元素 if(reader.isStartElement()){ //判断读取的根标签是否是bookindex if(reader.name() == "bookindex"){ //是bookindex 往下读取 readBookindexElement(); }else { reader.raiseError(tr("Not a valid book file")); } }else { reader.readNext(); } } //文件记得关闭 file.close(); if(reader.hasError()){ QMessageBox::information(this,tr("Error"),tr("Filed to parse file %1").arg(fileName)); return false; }else if(file.error() != QFile::NoError){ QMessageBox::information(this,tr("Error"),tr("Cannot read file %1").arg(fileName)); return false; } return true; }读取bookindex节点:
void MainWindow::readBookindexElement() { //Q_ASSERT()加断言 若进函数的时候 StartElement状态,或者说标签不是 bookindex,就认为出错 Q_ASSERT(reader.isStartElement() && reader.name()=="bookindex"); //往下读取 reader.readNext(); while (!reader.atEnd()) { //判断是结束节点,跳出 if(reader.isEndElement()){ reader.readNext(); break; } if(reader.isStartElement()){ //(bookindex的子元素为entry)开始处理entry if(reader.name() == "entry"){ //读取entry节点,(隐藏根节点) readEntryElement(treeWidget->invisibleRootItem()); }else { //没读到entry节点 跳过 skipUnknownElement(); } }else { reader.readNext(); } } }读取entry节点
//接受一个QTreeWidgetItem指针作为根节点.这个节点被当做这个 entry 标签在QTreeWidget中的根节点。 void MainWindow::readEntryElement(QTreeWidgetItem *parent) { QTreeWidgetItem *item = new QTreeWidgetItem(parent); //item index=0 属性为"term"的值 //QXmlStreamReader::attributes() Returns the attributes of a StartElement. item->setText(0,reader.attributes().value("term").toString()); reader.readNext(); while (!reader.atEnd()) { if(reader.isEndElement()){ reader.readNext(); break; } if(reader.isStartElement()){ //读到entry节点 if(reader.name() == "entry"){ readEntryElement(item); //page节点 }else if(reader.name() == "page"){ readPageElement(item); }else{ //无节点 跳过 skipUnknownElement(); } }else { reader.readNext(); } } }读取page
void MainWindow::readPageElement(QTreeWidgetItem *parent) { //获取文本 QString page = reader.readElementText(); if(reader.isEndElement()){ reader.readNext(); } //QTreeWidgetItem::text(int column)返回指定列的text QString allPages = parent->text(1); if(!allPages.isEmpty()){ //用","分割 allPages += ","; } allPages += page; parent->setText(1,allPages); }无关节点跳过
void MainWindow::skipUnknownElement() { reader.readNext(); //没有结束 while (!reader.atEnd()) { //结束 if(reader.isEndElement()){ reader.readNext(); break; } //继续跳过读取。 if(reader.isStartElement()){ skipUnknownElement(); }else { reader.readNext(); } } }在MainWindow函数中 声明
setWindowTitle(tr("xml reader")); treeWidget = new QTreeWidget(this); QStringList headers; //设置头 Items Pages headers<<"Items"<<"Pages"; treeWidget->setHeaderLabels(headers); setCentralWidget(treeWidget); //读取不到 用绝对路径读取成功 添加到资源路径读取成功 //readFile("D:/lei_project/qtproject/XMLdemo/books.xml"); readFile(":/xml/books.xml"); //readFile("books.xml")