zoukankan      html  css  js  c++  java
  • 39.Qt XML

    1.使用QXmlStreamReader读取XML,可以读取内存中容纳不了的特大文件,或者读取在XML文档中定制的文档的内容。

    xml文件(in1.xml)

    <?xml version="1.0"?>
    <bookindex>
        <entry term="sidebearings">
            <page>10</page>
            <page>34-35</page>
            <page>307-308</page>
        </entry>
        <entry term="subtraction">
            <entry term="of pictures">
                <page>115</page>
                <page>244</page>
            </entry>
            <entry term="of vectors">
                <page>9</page>
            </entry>
        </entry>
    </bookindex>

    main.cpp

     1 #include <QtGui>
     2 
     3 #include <iostream>
     4 #include "xmlstreamreader.h"
     5 
     6 int main(int argc, char *argv[])
     7 {
     8     //创建QApplication对象
     9     QApplication app(argc, argv);
    10     QDir::setCurrent(app.applicationDirPath());//设置路径为当前目录
    11     
    12     //创建两个标签
    13     QStringList labels;
    14     labels << QObject::tr("Terms") << QObject::tr("Pages");
    15 
    16     //树形控件窗口
    17     QTreeWidget treeWidget;
    18     //设置第一行
    19     treeWidget.setHeaderLabels(labels);
    20     //设置可以伸缩
    21     treeWidget.header()->setResizeMode(QHeaderView::Stretch);
    22     //设置窗口标题
    23     treeWidget.setWindowTitle(QObject::tr("XML Stream Reader"));
    24     //树形控件显示
    25     treeWidget.show();
    26 
    27     //创建对象,对xml读取
    28     XmlStreamReader reader(&treeWidget);
    29     
    30     reader.readFile("in1.xml");
    31 
    32     return app.exec();
    33 }

    xmlstreamreader.h

     1 #ifndef XMLSTREAMREADER_H
     2 #define XMLSTREAMREADER_H
     3 
     4 #include <QXmlStreamReader>
     5 
     6 class QTreeWidget;
     7 class QTreeWidgetItem;
     8 
     9 class XmlStreamReader
    10 {
    11 public:
    12     XmlStreamReader(QTreeWidget *tree);
    13 
    14     bool readFile(const QString &fileName);
    15 
    16 private:
    17     //解析一个含有0或0个以上<entry>元素的<bookindex>...</bookindex>
    18     void readBookindexElement();
    19     //解析一个含有0个或0个以上<entry>元素的<entry>...</entry>元素
    20     //以及嵌套任意层次的含有0或0个以上<entry>元素
    21     void readEntryElement(QTreeWidgetItem *parent);
    22     //解析一个<page>...</page>元素
    23     void readPageElement(QTreeWidgetItem *parent);
    24     //跳过不能识别的元素
    25     void skipUnknownElement();
    26 
    27     //保存传进来的treeWidget
    28     QTreeWidget *treeWidget;
    29     //读取对象
    30     QXmlStreamReader reader;
    31 };
    32 
    33 #endif

    xmlstreamreader.cpp

      1 #include <QtGui>
      2 #include <QtXml>
      3 #include <iostream>
      4 
      5 #include "xmlstreamreader.h"
      6 
      7 XmlStreamReader::XmlStreamReader(QTreeWidget *tree)
      8 {
      9     //初始化指针
     10     treeWidget = tree;
     11 }
     12 
     13 bool XmlStreamReader::readFile(const QString &fileName)
     14 {
     15     //尝试打开文件
     16     QFile file(fileName);
     17     //只读,文本方式打开。如果出错,返回出错信息。
     18     if (!file.open(QFile::ReadOnly | QFile::Text)) {
     19         std::cerr << "Error: Cannot read file " << qPrintable(fileName)
     20                   << ": " << qPrintable(file.errorString())
     21                   << std::endl;
     22         return false;
     23     }
     24 
     25     //如果成功,则将这个file设置为输入设备,用于读数据
     26     reader.setDevice(&file);
     27 
     28     //从流中读取一个数据
     29     reader.readNext();
     30     //如果没到文件末尾
     31     while (!reader.atEnd()) {
     32         //如果是开始标签
     33         if (reader.isStartElement()) {
     34             if (reader.name() == "bookindex") {
     35                 //解析bookindex
     36                 readBookindexElement();
     37             }
     38             else
     39             {
     40                 //否则给出出错信息
     41                 reader.raiseError(QObject::tr("Not a bookindex file"));
     42             }
     43         }
     44         else
     45         {
     46             //继续读下一个标签
     47             reader.readNext();
     48         }
     49     }
     50 
     51     file.close();
     52     //如果处理出现错误就会返回
     53     //是否存在解析错误?
     54     if (reader.hasError()) {
     55         std::cerr << "Error: Failed to parse file "
     56                   << qPrintable(fileName) << ": "
     57                   << qPrintable(reader.errorString()) << std::endl;
     58         return false;
     59     }
     60     //是否存在文件错误?
     61     else if (file.error() != QFile::NoError)
     62     {
     63         std::cerr << "Error: Cannot read file " << qPrintable(fileName)
     64                   << ": " << qPrintable(file.errorString())
     65                   << std::endl;
     66         return false;
     67     }
     68     return true;
     69 }
     70 
     71 void XmlStreamReader::readBookindexElement()
     72 {
     73     //读下一个标签
     74     reader.readNext();
     75     while (!reader.atEnd()) {
     76         //如果到结束标签,则结束while循环
     77         if (reader.isEndElement()) {
     78             reader.readNext();
     79             break;
     80         }
     81         
     82         
     83         //如果是开始标签
     84         if (reader.isStartElement()) 
     85         {
     86             if (reader.name() == "entry") 
     87             {
     88                 //调用处理entry的函数
     89                 readEntryElement(treeWidget->invisibleRootItem());
     90             }
     91             else 
     92             {
     93                 //调用未知的处理函数
     94                 skipUnknownElement();
     95             }
     96         } 
     97         else
     98         {
     99             //如果不是开始标签则读取下一个
    100             reader.readNext();
    101         }
    102     }
    103 }
    104 
    105 //每当遇到<entry>开始标签,就调用readEntryElement()函数
    106 void XmlStreamReader::readEntryElement(QTreeWidgetItem *parent)
    107 {
    108     //遇到一个<entry>就在树形控件中增加一个条目
    109     QTreeWidgetItem *item = new QTreeWidgetItem(parent);
    110     //设置第0个,为对应的term项所表示的值
    111     item->setText(0, reader.attributes().value("term").toString());
    112 
    113     //读下一个
    114     reader.readNext();
    115     while (!reader.atEnd()) {
    116         //如果遇到关闭标签,跳出循环
    117         if (reader.isEndElement()) {
    118             reader.readNext();
    119             break;
    120         }
    121 
    122         //如果遇到的是开始标签
    123         if (reader.isStartElement()) {
    124             //如果是<entry>标签
    125             if (reader.name() == "entry") {
    126                 //递归调用
    127                 readEntryElement(item);
    128             }
    129             //如果是<page>标签
    130             else if (reader.name() == "page")
    131             {
    132                 readPageElement(item);
    133             }
    134             //未知标签
    135             else
    136             {
    137                 skipUnknownElement();
    138             }
    139         }
    140         else
    141         {
    142             reader.readNext();
    143         }
    144     }
    145 }
    146 
    147 //读取页面信息
    148 void XmlStreamReader::readPageElement(QTreeWidgetItem *parent)
    149 {
    150     //读标签内容,调用reader.readElementText,reader会停留在结束标签位置上,需要跳过
    151     QString page = reader.readElementText();
    152     //如果是结束标识,则跳到下一个进行读取
    153     if (reader.isEndElement())
    154         reader.readNext();
    155 
    156     //第一个文本
    157     QString allPages = parent->text(1);
    158     //如果不为空加上,
    159     if (!allPages.isEmpty())
    160         allPages += ", ";
    161     //加上标签内容
    162     allPages += page;
    163     //设置
    164     parent->setText(1, allPages);
    165 }
    166 
    167 //如果遇到未知标签也读取,直到跳过该标签的关闭标签
    168 void XmlStreamReader::skipUnknownElement()
    169 {
    170     //遇到未知的继续读取下一个标签
    171     reader.readNext();
    172     //继续读下一个,如果没到末尾
    173     while (!reader.atEnd()) {
    174         if (reader.isEndElement()) {
    175             reader.readNext();
    176             break;
    177         }
    178 
    179         //如果是开始,继续递归,直到遇到第一个未知的关闭标签
    180         if (reader.isStartElement()) {
    181             skipUnknownElement();
    182         } else {
    183             reader.readNext();
    184         }
    185     }
    186 }
  • 相关阅读:
    aa
    ECS上搭建Docker(CentOS7)
    mysql时间戳转日期
    rsync用法
    docker安装mysql8
    使用Docker安装mysql,挂载外部配置和数据
    my.cnf
    Centos7通过yum安装jdk8
    maven添加本地包命令mvn install:install-file
    Mysql——查看数据库,表占用磁盘大小
  • 原文地址:https://www.cnblogs.com/xiaochi/p/9026986.html
Copyright © 2011-2022 走看看