[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文件,将其内容更改为:

  1. #ifndef MYSAX_H
  2. #define MYSAX_H
  3. #include <QXmlDefaultHandler>
  4. class QListWidget;
  5. class MySAX : public QXmlDefaultHandler
  6. {
  7. public:
  8.     MySAX();
  9.     ~MySAX();
  10.     bool readFile(const QString &fileName);
  11. protected:
  12. bool startElement(const QString &namespaceURI, 
  13. const QString &localName,
  14.                           const QString &qName, 
  15. const QXmlAttributes &atts);
  16. bool endElement(const QString &namespaceURI, 
  17. const QString &localName,
  18.                     const QString &qName);
  19.     bool characters(const QString &ch);
  20.     bool fatalError(const QXmlParseException &exception);
  21. private:
  22.     QListWidget *list;
  23.     QString currentText;
  24. };
  25. #endif // MYSAX_H

复制代码

这里主要是重新声明了QXmlDefaultHandler类的startElement()、endElement()、characters()和fatalError()几个函数,readFile()函数用来读入XML文件,QListWidget部件用来显示解析后的XML文档内容,currentText字符串变量用于暂存字符数据。

6.打开mysax.cpp文件,将其内容修改如下:

  1. #include "mysax.h"
  2. #include <QtXml>
  3. #include <QListWidget>
  4. MySAX::MySAX()
  5. {
  6.     list = new QListWidget;
  7.     list->show();
  8. }
  9. MySAX::~MySAX()
  10. {
  11.     delete list;
  12. }
  13. bool MySAX::readFile(const QString &fileName)
  14. {
  15.     QFile file(fileName);
  16.     
  17.     // 读取文件内容
  18.     QXmlInputSource inputSource(&file);
  19.     
  20.     // 建立QXmlSimpleReader对象
  21.     QXmlSimpleReader reader;
  22.     
  23.     // 设置内容处理器
  24.     reader.setContentHandler(this);
  25.     
  26.     // 设置错误处理器
  27.     reader.setErrorHandler(this);
  28.     
  29.     // 解析文件
  30.     return reader.parse(inputSource);
  31. }
  32. // 已经解析完一个元素的起始标签
  33. bool MySAX::startElement(const QString &namespaceURI, 
  34. const QString &localName,
  35.                          const QString &qName, 
  36. const QXmlAttributes &atts)
  37. {
  38.     if (qName == "library")
  39.         list->addItem(qName);
  40.     else if (qName == "book")
  41.         list->addItem("    " + qName + atts.value("id"));
  42.     return true;
  43. }
  44. // 已经解析完一块字符数据
  45. bool MySAX::characters(const QString &ch)
  46. {
  47.     currentText = ch;
  48.     return true;
  49. }
  50. // 已经解析完一个元素的结束标签
  51. bool MySAX::endElement(const QString &namespaceURI, 
  52. const QString &localName,
  53.                        const QString &qName)
  54. {
  55.     if (qName == "title" || qName == "author")
  56.         list->addItem("        " + qName + " : " + currentText);
  57.     return true;
  58. }
  59. // 错误处理
  60. bool MySAX::fatalError(const QXmlParseException &exception)
  61. {
  62.     qDebug() << exception.message();
  63.     return false;
  64. }

复制代码

这里添加了几个函数的定义。在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) 
时间: 2024-11-03 15:24:28

[Qt教程] 第29篇 XML(三)Qt中的SAX的相关文章

[Qt教程] 第27篇 XML(一)使用DOM读取XML文档

[Qt教程] 第27篇 XML(一)使用DOM读取XML文档 楼主  发表于 2013-5-21 21:14:28 | 查看: 1001| 回复: 14 使用DOM读取XML文档 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 XML(ExtensibleMarkup Language,可扩展标记语言),是一种类似于HTML的标记语言,但它的设计目的是用来传输数据,而不是显示数据.XML的标签没有被预定义,用户需要在使用时自行进行定义.XML是W3C(万维网联盟)的推荐标

[Qt教程] 第28篇 XML(二)使用DOM创建和操作XML文档

[Qt教程] 第28篇 XML(二)使用DOM创建和操作XML文档 楼主  发表于 2013-5-21 22:00:51 | 查看: 475| 回复: 0 使用DOM创建和操作XML文档 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 在上一节中我们用手写的方法建立了一个XML文档,并且用DOM的方法对其进行了读取.现在我们使用代码来创建那个XML文档,并且对它实现查找.更新.插入等操作. 环境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2

[Qt教程] 第30篇 XML(四)使用流读写XML

[Qt教程] 第30篇 XML(四)使用流读写XML 楼主  发表于 2013-5-22 13:03:33 | 查看: 611| 回复: 0 使用流读写XML 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语        从Qt 4.3开始引入了两个新的类来读取和写入XML文档:QXmlStreamReader和QXmlStreamWriter. QXmlStreamReader类提供了一个快速的解析器通过一个简单的流API来读取格式良好的XML文档,它是作为Qt的SAX

[Qt教程] 第23篇 数据库(三)利用QSqlQuery类执行SQL语句

[Qt教程] 第23篇 数据库(三)利用QSqlQuery类执行SQL语句 楼主  发表于 2013-5-15 22:39:29 | 查看: 813| 回复: 0 利用QSqlQuery类执行SQL语句 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语        SQL即结构化查询语言,是关系数据库的标准语言.前面两节中已经在Qt里利用QSqlQuery类执行了SQL语句,这一节我们将详细讲解该类的使用.需要说明,因为我们重在讲解Qt中的数据库使用,而非专业的讲解数据库

[Qt教程] 第43篇 进阶(三)对象树与拥有权

[Qt教程] 第43篇 进阶(三)对象树与拥有权 楼主  发表于 2013-9-12 16:39:33 | 查看: 255| 回复: 1 对象树与拥有权 版权声明 该文章原创于Qter开源社区 导语 学习完前面的内容,大家对应用Qt编程应该已经有了一个大概的印象.后面的内容我们将介绍Qt中的一些核心机制,它们是构成Qt的基础,包括对象模型.信号和槽.对象树与拥有权等.在前面使用Qt编程时,大家对一些内容可能存在疑惑,学习完下面的知识,可以帮助大家更好的使用Qt进行编程. 环境:Windows X

[Qt教程] 第33篇 网络(三)FTP(一)

[Qt教程] 第33篇 网络(三)FTP(一) 楼主  发表于 2013-9-4 14:52:46 | 查看: 392| 回复: 8 FTP(一) 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 上一节我们讲述了HTTP的编程,这一节讲述与其及其相似的FTP的编程.FTP即FileTransfer Protocol,也就是文件传输协议.FTP的主要作用,就是让用户连接上一个远程计算机,查看远程计算机有哪些文件,然后把文件从远程计算机上拷贝到本地计算机,或者把本地计算机的文

[Qt教程] 第13篇 2D绘图(三)绘制文字

[Qt教程] 第13篇 2D绘图(三)绘制文字 楼主  发表于 2013-4-25 23:04:46 | 查看: 720| 回复: 0 绘制文字 版权声明 该文章原创于Qter开源社区,作者yafeilinux,转载请注明出处! 导语 Qt中除了绘制图形以外,还可以使用QPainter::darwText()函数来绘制文字,也可以使用QPainter::setFont()设置文字所使用的字体,使用QPainter::fontInfo()函数可以获取字体的信息,它返回QFontInfo类对象.在绘

[Qt教程] 第46篇 进阶(六) 国际化

[Qt教程] 第46篇 进阶(六) 国际化 楼主  发表于 2013-10-7 09:23:45 | 查看: 109| 回复: 0 国际化 版权声明 该文章原创于Qter开源社区 导语 在第2篇中讲述如何显示中文时,曾提到使用QTextCodec和tr()的方式直接显示中文,其实这只是一种临时的方法,方便我们快速完成程序,显示效果.当真正要发布一个程序时,最好的方式是在程序中使用英文字符串,而后使用国际化工具进行翻译. 国际化的英文表述为Internationalization,通常简写为I18

[Qt教程] 第21篇 数据库(一)Qt数据库应用简介

[Qt教程] 第21篇 数据库(一)Qt数据库应用简介 楼主  发表于 2013-5-13 20:56:39 | 查看: 1403| 回复: 13 Qt数据库应用简介 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 下面十节讲解数据库和XML的相关内容.在学习数据库相关内容前,建议大家掌握一些基本的SQL知识,应该可以看懂基本的SELECT.INSERT.UPDATE和DELETE等语句,因为在这几篇教程中使用的都是非常简单的操作,所以即便没有数据库的专业知识也可以看懂!