QT XML文档的解析 QXmlStreamReader, DOM,SAX 三种解析方法 简单示例
0. xml文档如下
<?xml version="1.0"?> <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>
1. 用QXmlStreamReader 解析
使用QT时需要添加xml模块, 修改工程文件.pro,QT+=xml
//#include "widget.h" #include <QApplication> #include <QtGui> #include <qxmlstream.h> #include <iostream> #include <QDebug> QXmlStreamReader reader; bool readFile(const QString &fileName); void readBookindexElement(); //解析含有0或以上<entry>元素的 <bookindex> ... </bookindex> void readEntryElement(); //解析含有0或以上<page>元素的<entry> ... </entry> void skipUnknowElement(); //跳过不认识的元素 void readPageElement(); //解析一个<page> ... </page> 元素 bool 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; } reader.setDevice(&file); reader.readNext(); while( !reader.atEnd() ) { if( reader.isStartElement() ) { qDebug() << "reader.name: " << reader.name(); if( reader.name() == "bookindex" ) { qDebug() << "start element: bookindex"; readBookindexElement(); break; } else { qDebug() << "not a right start element"; reader.raiseError(QObject::tr("not a right start element")); } } else reader.readNext(); } file.close(); } void readBookindexElement() { reader.readNext(); while( !reader.atEnd() ) { if(reader.isEndElement()) { reader.readNext(); break; } if(reader.isStartElement()) { if( reader.name() == "entry" ) { readEntryElement(); } else skipUnknowElement(); } else reader.readNext(); } } void readEntryElement() { //qDebug() << "readEntryElement"; reader.readNext(); while(!reader.atEnd()) { if(reader.isEndElement()) { reader.readNext(); break; } if(reader.isStartElement()) { if( reader.name() == "entry" ) readEntryElement(); else if( reader.name() == "page" ) readPageElement(); else skipUnknowElement(); } else reader.readNext(); } } void skipUnknowElement() { //qDebug() << "skipUnknowElement"; reader.readNext(); while(!reader.atEnd()) { if( reader.isEndElement() ) { reader.readNext(); break; } if(reader.isStartElement()) skipUnknowElement(); else reader.readNext(); } } void readPageElement() { //qDebug() << "readPageElement"; QString page = reader.readElementText(); if( reader.isEndElement() ) reader.readNext(); qDebug() << "page: " << page; } int main(int argc, char *argv[]) { readFile("77.xml"); return 0; }
2. 用DOM方式解析
使用QT时需要添加xml模块, 修改工程文件.pro,QT+=xml
#include "widget.h" #include <QApplication> #include <QtGui> #include <QDomElement> #include <QDebug> #include <iostream> bool readFile(const QString &fileName); void parseBookindexElement(const QDomElement &element); void parseEntryElement(const QDomElement &element); void parsePageElement(const QDomElement &element); bool readFile(const QString &fileName) { //qDebug() << "readFile"; 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; } QString errorStr; int errorLine; int errorColumn; QDomDocument doc; if( !doc.setContent(&file, false, &errorStr, &errorLine, &errorColumn) ) { std::cerr << "Error: Parse error at line " << errorLine <<"," << "column " << errorColumn << "," << qPrintable(errorStr) << std::endl; return false; } QDomElement root = doc.documentElement(); if( root.tagName() != "bookindex" ) { std::cerr << "Error: root element is not right" << std::endl; return false; } parseBookindexElement(root); return true; } void parseBookindexElement(const QDomElement &element) { //qDebug() << "parseBookindexElement"; QDomNode child = element.firstChild(); while(!child.isNull()) { if( child.toElement().tagName() == "entry" ) parseEntryElement(child.toElement()); child = child.nextSibling(); } } void parseEntryElement(const QDomElement &element) { //qDebug() << "parseEntryElement"; QDomNode child = element.firstChild(); while(!child.isNull()) { if( child.toElement().tagName() == "entry" ) parseEntryElement(child.toElement()); else if( child.toElement().tagName() == "page" ) parsePageElement(child.toElement()); child = child.nextSibling(); } } void parsePageElement(const QDomElement &element) { //qDebug() << "parsePageElement"; QString page = element.text(); qDebug() << "page: " << page; } int main(int argc, char *argv[]) { readFile("77.xml"); return 0; }