生活随笔
收集整理的這篇文章主要介紹了
[Qt教程] 第29篇 XML(三)Qt中的SAX
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[Qt教程]?第29篇 XML(三)Qt中的SAX
樓主 ?
發表于 2013-5-21 22:27:59?
|?查看: 615
|?回復: 5
Qt中的SAX 版權聲明 該文章原創于Qter開源社區(www.qter.org),作者yafeilinux,轉載請注明出處! 導語 我們前面講述了用DOM的方法對XML文檔進行操作,DOM實現起來很靈活,但是這樣也就使得編程變得復雜了些,而且我們前面也提到過,DOM需要預先把整個XML文檔都讀入內存,這樣就使得它不適合處理較大的文件。下面我們講述另一種讀取XML文檔的方法,即SAX 。是的,如果你只想讀取并顯示整個XML文檔,那么SAX是很好的選擇,因為它提供了比DOM更簡單的接口,并且它不需要將整個XML文檔一次性讀入內存,這樣便可以用來讀取較大的文件。我們對SAX不再進行過多的介紹,因為不需要任何基礎,你就可以掌握我們下面要講的內容了。如果大家對SAX有興趣,可以到網上查找相關資料。 環境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2 目錄 一、解析器解析流程 二、使用SAX讀取文檔 正文 一、解析器解析流程 在Qt的QtXml模塊中提供了一個QXmlSimpleReader的類,它便是基于SAX的XML解析器。這個解析器是基于事件的,但這些事件由它們自身進行關聯,我們并不需要進行設置。我們只需知道,當解析器解析一個XML的元素時,就會執行相應的事件,我們只要重寫這些事件處理函數,就能讓它按照我們的想法進行解析。 比如要解析下面的元素: <title>Qt</title> 解析器會依次調用如下事件處理函數:startElement(),characters(),endElement()。我們可以在startElement()中獲得元素名(如“title”)和屬性,在characters()中獲得元素中的文本(如“Qt”),在endElement()中進行一些結束讀取該元素時想要進行的操作。而所有的這些事件處理函數我們都可以通過繼承QXmlDefaultHandler類來重寫。 二、使用SAX讀取文檔 1.新建其他項目分類中的空的Qt項目,項目名稱為mySAX。 2.完成后向項目中添加新的C++類,類名為“MySAX”,基類填寫QXmlDefaultHandler。 3.然后再添加一個main.cpp文件。 4.先打開mySAX.pro文件,添加一行代碼:QT+= xml,然后保存該文件。 5.打開mysax.h文件,將其內容更改為: #ifndef MYSAX_H #define MYSAX_H #include <QXmlDefaultHandler> class QListWidget; class MySAX : public QXmlDefaultHandler { public: ? ? MySAX(); ? ? ~MySAX(); ? ? bool readFile(const QString &fileName); protected: bool startElement(const QString &namespaceURI,? const QString &localName, ? ?? ?? ?? ?? ?? ?? ?? ???const QString &qName,? const QXmlAttributes &atts); bool endElement(const QString &namespaceURI,? const QString &localName, ? ?? ?? ?? ?? ?? ???const QString &qName); ? ? bool characters(const QString &ch); ? ? bool fatalError(const QXmlParseException &exception); private: ? ? QListWidget *list; ? ? QString currentText; }; #endif // MYSAX_H 復制代碼 這里主要是重新聲明了QXmlDefaultHandler類的startElement()、endElement()、characters()和fatalError()幾個函數,readFile()函數用來讀入XML文件,QListWidget部件用來顯示解析后的XML文檔內容,currentText字符串變量用于暫存字符數據。 6.打開mysax.cpp文件,將其內容修改如下: #include "mysax.h" #include <QtXml> #include <QListWidget> MySAX::MySAX() { ? ? list = new QListWidget; ? ? list->show(); } MySAX::~MySAX() { ? ? delete list; } bool MySAX::readFile(const QString &fileName) { ? ? QFile file(fileName); ? ?? ? ? // 讀取文件內容 ? ? QXmlInputSource inputSource(&file); ? ?? ? ? // 建立QXmlSimpleReader對象 ? ? QXmlSimpleReader reader; ? ?? ? ? // 設置內容處理器 ? ? reader.setContentHandler(this); ? ?? ? ? // 設置錯誤處理器 ? ? reader.setErrorHandler(this); ? ?? ? ? // 解析文件 ? ? return reader.parse(inputSource); } // 已經解析完一個元素的起始標簽 bool MySAX::startElement(const QString &namespaceURI,? const QString &localName, ? ?? ?? ?? ?? ?? ?? ?? ? const QString &qName,? const QXmlAttributes &atts) { ? ? if (qName == "library") ? ?? ???list->addItem(qName); ? ? else if (qName == "book") ? ?? ???list->addItem("? ? " + qName + atts.value("id")); ? ? return true; } // 已經解析完一塊字符數據 bool MySAX::characters(const QString &ch) { ? ? currentText = ch; ? ? return true; } // 已經解析完一個元素的結束標簽 bool MySAX::endElement(const QString &namespaceURI,? const QString &localName, ? ?? ?? ?? ?? ?? ?? ???const QString &qName) { ? ? if (qName == "title" || qName == "author") ? ?? ???list->addItem("? ?? ???" + qName + " : " + currentText); ? ? return true; } // 錯誤處理 bool MySAX::fatalError(const QXmlParseException &exception) { ? ? qDebug() << exception.message(); ? ? return false; } 復制代碼 這里添加了幾個函數的定義。在readFile()函數中,我們設置了文件的解析過程。Qt中提供了一個簡單的XML解析器QXmlSimpleReader,它是基于SAX的。該解析器需要QXmlInputSource為其提供數據,QXmlInputSource會使用相應的編碼來讀取XML文檔的數據。在進行解析之前,還需要使用setContentHandler()來設置事件處理器,使用setErrorHandler()來設置錯誤處理器,它們的參數使用了this,表明使用本類作為處理器,也就是在解析過程中出現的各種事件都會使用本類的startElement()等事件處理函數來進行處理,而出現錯誤時會使用本類的fatalError()函數來處理。最后,調用了parse()函數來進行解析,該函數會在解析成功時返回true,否則返回false。在后面的幾個事件處理函數中,就是簡單的將數據顯示在QListWidget中。 7.最后打開main.cpp文件,添加如下內容: #include?"mysax.h" #include?<QApplication> int?main(int?argc,?char*?argv[]) {? ?? ? ?? ?QApplication?app(argc,?argv);? ?? ? ?? ?MySAX?sax;? ? ? ?? ?sax.readFile("../mySAX/my.xml");? ?? ? ?? ?return?app.exec(); }? 8.將前面第27篇建立的“my.xml”文件復制到我們的源碼目錄中,然后運行程序,效果如下圖所示。 結語 可以看到使用SAX方法來解析XML文檔比使用DOM方法要清晰很多,更重要的是它的效率要高很多,不過SAX方法只適用于讀取XML文檔。 涉及到的源碼:??mySAX.zip?(2.09 KB, 下載次數: 8)? |
總結
以上是生活随笔為你收集整理的[Qt教程] 第29篇 XML(三)Qt中的SAX的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。