XML文件处理

来源:互联网 发布:archlinux如何配置网络 编辑:程序博客网 时间:2024/06/10 09:39

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

SAX方式解析XML文件

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


代码示例如下:

myhandler.h

#ifndef MYHANDLER_H#define MYHANDLER_H#include <QXmlDefaultHandler>class QString;class MyHandler : public QXmlDefaultHandler{public:    explicit MyHandler();signals:public slots:public:  bool startDocument();  bool startElement( const QString & namespaceURI,                     const QString & localName,                     const QString & qName,                     const QXmlAttributes & atts);  bool characters(const QString& text);  bool endElement( const QString & namespaceURI,                   const QString & localName,                   const QString & qName );private:  QString indent;};#endif // MYHANDLER_H

myhandler.cpp

#include "myhandler.h"#include <QObject>#include <QTextStream>#include <QDebug>MyHandler::MyHandler():QXmlDefaultHandler(){    }bool MyHandler::startDocument() {    indent = "";    return TRUE;}bool MyHandler::characters(const QString& text) {    QString t = text;    qDebug() << t.remove('\n');    return TRUE;}bool MyHandler::startElement( const QString&,                              const QString&,                              const QString& qName,                              const QXmlAttributes& atts) {    QString str = QString("\n%1\\%2").arg(indent).arg(qName);    qDebug() << str;    if (atts.length()>0) {        QString fieldName = atts.qName(0);        QString fieldValue = atts.value(0);        qDebug() << QString("(%2=%3)").arg(fieldName).arg(fieldValue);    }    qDebug() << "{";    indent += "    ";    return TRUE;}bool MyHandler::endElement( const QString&,                            const QString& ,                            const QString& ) {    indent.remove( 0, 4 );    qDebug() << "}";    return TRUE;}

main.cpp

#include <QApplication>#include <QFile>#include <QXmlInputSource>#include "myhandler.h"#include <QDebug>int main(int argc, char *argv[]){    QApplication a(argc, argv);    QFile xmlFile( ":/test.xml" );    QXmlInputSource source( &xmlFile );    if (!xmlFile.open(QFile::ReadOnly | QFile::Text)) {         return -1;    }    MyHandler handler;    QXmlSimpleReader reader;    reader.setContentHandler( &handler );   if( reader.parse( source ) )       qDebug()<<"File loaded!";    return a.exec();    }

DOM方式解析XML文件

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

#include <QtCore/QCoreApplication>#include <QDomDocument>#include <QFile>#include <QDebug>void parseFolderElement(const QDomElement &element){    QDomElement child = element.firstChildElement();    while (!child.isNull()) {        if (child.tagName() == "folder") {              parseFolderElement(child);        } else if (child.tagName() == "bookmark") {            QString title = child.firstChildElement("title").text();            if (title.isEmpty())                title = QObject::tr("Folder");            qDebug()<<"title="<<title;        } else if (child.tagName() == "separator") {             qDebug()<<"processing separator";        }        child = child.nextSiblingElement();    }}void parseXmlByDom(QIODevice *device){    QDomDocument domDocument;    QString errorStr;    int errorLine;    int errorColumn;    if (!domDocument.setContent(device, true, &errorStr, &errorLine,                                &errorColumn)) {        qDebug()<<"Parse error at line "                      <<errorLine                      <<", column "                      << errorColumn                      <<":\n"                      <<errorStr;        return;    }    QDomElement root = domDocument.documentElement();    if (root.tagName() != "xbel") {        qDebug()<<QString( "The file is not an XBEL file.");        return;    } else if (root.hasAttribute("version")               && root.attribute("version") != "1.0") {        qDebug()<<QString("The file is not an XBEL version 1.0 file.");        return;    }    QDomElement child = root.firstChildElement("folder");    while (!child.isNull()) {        parseFolderElement(child);        child = child.nextSiblingElement("folder");    }}int main(int argc, char *argv[]){    QCoreApplication a(argc, argv);    QFile f("frank.xbel");   if( ! f.open(QIODevice::ReadOnly) )   {       qDebug()<<"failed to open file";       return -1;   }   parseXmlByDom(&f);    return a.exec();}