XML文件处理

来源:互联网 发布:平面设计手机作图软件 编辑:程序博客网 时间:2024/06/06 09:00

QtXML模块包含了两种处理xmlAPI,分别是SAXDOMSAX提供了一种低层的基于事件驱动的方式解析xml文件,而DOM提供了一种高层的接口用于解析xml文件。不同之处在于DOM受制于内存的大小,一次不能解析文件大小太大的xml文件,因为它将xml文件一次性地读入内存中。

SAX方式解析XML文件

SAX方式解析XML是基于事件方式编程的。执行的流程完全取决于读入的数据。使用该方式的主要步骤是创建一个XML读取器以及一个处理器,然后将两者关联起来,之后调用parse(),涉及的各方用类图表示如下:


代码示例如下:

myhandler.h

[cpp] view plaincopy
  1. #ifndef MYHANDLER_H  
  2. #define MYHANDLER_H  
  3. #include <QXmlDefaultHandler>  
  4. class QString;  
  5. class MyHandler : public QXmlDefaultHandler  
  6. {  
  7. public:  
  8.     explicit MyHandler();  
  9. signals:  
  10. public slots:  
  11. public:  
  12.   bool startDocument();  
  13.   bool startElement( const QString & namespaceURI,  
  14.                      const QString & localName,  
  15.                      const QString & qName,  
  16.                      const QXmlAttributes & atts);  
  17.   bool characters(const QString& text);  
  18.   bool endElement( const QString & namespaceURI,  
  19.                    const QString & localName,  
  20.                    const QString & qName );  
  21. private:  
  22.   QString indent;  
  23. };  
  24. #endif // MYHANDLER_H  

myhandler.cpp

[cpp] view plaincopy
  1. #include "myhandler.h"  
  2. #include <QObject>  
  3. #include <QTextStream>  
  4. #include <QDebug>  
  5. MyHandler::MyHandler():QXmlDefaultHandler()  
  6. {      
  7. }  
  8. bool MyHandler::startDocument() {  
  9.     indent = "";  
  10.     return TRUE;  
  11. }  
  12. bool MyHandler::characters(const QString& text) {  
  13.     QString t = text;  
  14.     qDebug() << t.remove('\n');  
  15.     return TRUE;  
  16. }  
  17. bool MyHandler::startElement( const QString&,  
  18.                               const QString&,  
  19.                               const QString& qName,  
  20.                               const QXmlAttributes& atts) {  
  21.     QString str = QString("\n%1\\%2").arg(indent).arg(qName);  
  22.     qDebug() << str;  
  23.     if (atts.length()>0) {  
  24.         QString fieldName = atts.qName(0);  
  25.         QString fieldValue = atts.value(0);  
  26.         qDebug() << QString("(%2=%3)").arg(fieldName).arg(fieldValue);  
  27.     }  
  28.     qDebug() << "{";  
  29.     indent += "    ";  
  30.     return TRUE;  
  31. }  
  32. bool MyHandler::endElement( const QString&,  
  33.                             const QString& ,  
  34.                             const QString& ) {  
  35.     indent.remove( 0, 4 );  
  36.     qDebug() << "}";  
  37.     return TRUE;  
  38. }  

main.cpp

[cpp] view plaincopy
  1. #include <QApplication>  
  2. #include <QFile>  
  3. #include <QXmlInputSource>  
  4. #include "myhandler.h"  
  5. #include <QDebug>  
  6. int main(int argc, char *argv[])  
  7. {  
  8.     QApplication a(argc, argv);  
  9.     QFile xmlFile( ":/test.xml" );  
  10.     QXmlInputSource source( &xmlFile );  
  11.     if (!xmlFile.open(QFile::ReadOnly | QFile::Text)) {  
  12.          return -1;  
  13.     }  
  14.     MyHandler handler;  
  15.     QXmlSimpleReader reader;  
  16.     reader.setContentHandler( &handler );  
  17.    if( reader.parse( source ) )  
  18.        qDebug()<<"File loaded!";  
  19.     return a.exec();  
  20.     }  

DOM方式解析XML文件

DOM方式只适合解析小的xml文件,它是基于SAX之上的一种高层解析XML方法。使用方式见如下代码所示:

[cpp] view plaincopy
  1. #include <QtCore/QCoreApplication>  
  2. #include <QDomDocument>  
  3. #include <QFile>  
  4. #include <QDebug>  
  5. void parseFolderElement(const QDomElement &element)  
  6. {  
  7.     QDomElement child = element.firstChildElement();  
  8.     while (!child.isNull()) {  
  9.         if (child.tagName() == "folder") {  
  10.               parseFolderElement(child);  
  11.         } else if (child.tagName() == "bookmark") {  
  12.             QString title = child.firstChildElement("title").text();  
  13.             if (title.isEmpty())  
  14.                 title = QObject::tr("Folder");  
  15.             qDebug()<<"title="<<title;  
  16.         } else if (child.tagName() == "separator") {  
  17.              qDebug()<<"processing separator";  
  18.         }  
  19.         child = child.nextSiblingElement();  
  20.     }  
  21. }  
  22. void parseXmlByDom(QIODevice *device)  
  23. {  
  24.     QDomDocument domDocument;  
  25.     QString errorStr;  
  26.     int errorLine;  
  27.     int errorColumn;  
  28.     if (!domDocument.setContent(device, true, &errorStr, &errorLine,  
  29.                                 &errorColumn)) {  
  30.         qDebug()<<"Parse error at line "  
  31.                       <<errorLine  
  32.                       <<", column "  
  33.                       << errorColumn  
  34.                       <<":\n"  
  35.                       <<errorStr;  
  36.         return;  
  37.     }  
  38.     QDomElement root = domDocument.documentElement();  
  39.     if (root.tagName() != "xbel") {  
  40.         qDebug()<<QString( "The file is not an XBEL file.");  
  41.         return;  
  42.     } else if (root.hasAttribute("version")  
  43.                && root.attribute("version") != "1.0") {  
  44.         qDebug()<<QString("The file is not an XBEL version 1.0 file.");  
  45.         return;  
  46.     }  
  47.     QDomElement child = root.firstChildElement("folder");  
  48.     while (!child.isNull()) {  
  49.         parseFolderElement(child);  
  50.         child = child.nextSiblingElement("folder");  
  51.     }  
  52. }  
  53. int main(int argc, char *argv[])  
  54. {  
  55.     QCoreApplication a(argc, argv);  
  56.     QFile f("frank.xbel");  
  57.    if( ! f.open(QIODevice::ReadOnly) )  
  58.    {  
  59.        qDebug()<<"failed to open file";  
  60.        return -1;  
  61.    }  
  62.    parseXmlByDom(&f);  
  63.     return a.exec();  
  64. }  
1 0
原创粉丝点击