• 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 }
  • 相关阅读:
    记一次博客被日的分析过程
    省钱版----查找 IoT 设备TTL线序__未完待续
    于bugku中游荡意外得到关于CBC翻转攻击思路
    清除浮动技巧总结
    程序猿的幸福
    Memcachedclientutils类
    leetcode 2 Add Two Numbers
    arduino小车入门教学——第三天(arduino基础)
    SAP MM模块 经常使用函数
    Java代码格式
  • 原文地址:https://www.cnblogs.com/xiaochi/p/9028363.html
Copyright © 2020-2023  润新知