41.使用SAX读取XML

main.cpp

 1 #include <QtGui>
 2 #include <iostream>
 3 
 4 #include "saxhandler.h"
 5 
 6 int main(int argc, char *argv[])
 7 {
 8     QApplication app(argc, argv);
 9     QDir::setCurrent(app.applicationDirPath());//设置路径为当前目录
10 
11 
12     QStringList labels;
13     labels << QObject::tr("Terms") << QObject::tr("Pages");
14 
15     QTreeWidget treeWidget;
16     treeWidget.setHeaderLabels(labels);
17     treeWidget.header()->setResizeMode(QHeaderView::Stretch);
18     treeWidget.setWindowTitle(QObject::tr("SAX Handler"));
19     treeWidget.show();
20 
21     SaxHandler handler(&treeWidget);
22     handler.readFile("in1.xml");
23 
24     return app.exec();
25 }

saxhandler.h

#ifndef SAXHANDLER_H
#define SAXHANDLER_H

#include <QXmlDefaultHandler>

class QTreeWidget;
class QTreeWidgetItem;

class SaxHandler : public QXmlDefaultHandler
{
public:
    SaxHandler(QTreeWidget *tree);

    bool readFile(const QString &fileName);

protected:
    bool startElement(const QString &namespaceURI,
                      const QString &localName,
                      const QString &qName,
                      const QXmlAttributes &attributes);
    bool endElement(const QString &namespaceURI,
                    const QString &localName,
                    const QString &qName);
    bool characters(const QString &str);
    bool fatalError(const QXmlParseException &exception);

private:
    //树控件窗口
    QTreeWidget *treeWidget;
    //树控件项
    QTreeWidgetItem *currentItem;
    QString currentText;
};

#endif

saxhandler.cpp

 1 #include <QtGui>
 2 #include <iostream>
 3 
 4 #include "saxhandler.h"
 5 
 6 SaxHandler::SaxHandler(QTreeWidget *tree)
 7 {
 8     treeWidget = tree;
 9 }
10 
11 //接受用存储在XML文件中的信息进行组装的QTreeWidget
12 //要获得要解析文件的文件名时,会调用这个函数.
13 bool SaxHandler::readFile(const QString &fileName)
14 {
15     currentItem = 0;
16 
17     QFile file(fileName);
18     //用来读取文件
19     QXmlInputSource inputSource(&file);
20     //用来解析这个文件
21     QXmlSimpleReader reader;
22     reader.setContentHandler(this);
23     reader.setErrorHandler(this);
24     //调用pause来进行解析
25     return reader.parse(inputSource);
26 }
27 
28 //当阅读器遇到一个新的打开标签时,就会调用startElement()函数.
29 //第三个参数是标签的名称,第四个参数是属性列表.
30 bool SaxHandler::startElement(const QString & /* namespaceURI */,
31                               const QString & /* localName */,
32                               const QString &qName,
33                               const QXmlAttributes &attributes)
34 {
35     //如果是<entry>
36     if (qName == "entry") {
37         //创建一个新的QTreeWidgetItem项,如果currentItem存在则以此为
38         //父对象,如果不存在则以treeWidget根为父对象
39         currentItem = new QTreeWidgetItem(currentItem ?
40                 currentItem : treeWidget->invisibleRootItem());
41         //设置文本
42         currentItem->setText(0, attributes.value("term"));
43     } 
44     else if (qName == "page")
45     {
46         //currentText是一个累加器,用于处理<page>之间的文本
47         currentText.clear();
48     }
49     return true;
50 }
51 
52 //可以把字符数据添加到currentText变量中,当遇到字符数据时进行操作
53 bool SaxHandler::characters(const QString &str)
54 {
55     currentText += str;
56     return true;
57 }
58 
59 //当遇到一个关闭标签会调用endElement.第三个参数是标签的名称.
60 bool SaxHandler::endElement(const QString & /* namespaceURI */,
61                             const QString & /* localName */,
62                             const QString &qName)
63 {
64     //如果是</entry>则更新currentItem私有变量
65     //使它指向当前QTreeWidgetItem的父对象
66     if (qName == "entry") {
67         currentItem = currentItem->parent();
68     } 
69     //如果为</page>,则把指定的页码或者范围添加到这一列当前项的文本
70     else if (qName == "page") 
71     {
72         if (currentItem) 
73         {
74             QString allPages = currentItem->text(1);
75             if (!allPages.isEmpty())
76                 allPages += ", ";
77             allPages += currentText;
78             currentItem->setText(1, allPages);
79         }
80     }
81     return true;
82 }
83 
84 //解析失败会调用fatalError函数,给出行号,列号,以及这个解析器的错误文本
85 bool SaxHandler::fatalError(const QXmlParseException &exception)
86 {
87     std::cerr << "Parse error at line " << exception.lineNumber()
88               << ", " << "column " << exception.columnNumber() << ": "
89               << qPrintable(exception.message()) << std::endl;
90     return false;
91 }

猜你喜欢

转载自www.cnblogs.com/xiaochi/p/9028363.html