Qt开发(六)使用QXmlStreamReader 读取 XML

1. QXmlStreamReader概述

1. 在 [ 使用 DOM 读取 XML] 中介绍了如何使用 DOM 文档对象模型的方式来读写 XML的方法。在 Qt 中使用DOM方式来去写 XML文件是非常方便的,但是存在一个缺点,那就是当 XML 文件比较大的时候,使用 DOM 将该 XML 文件内容加载到内存中的时候,会比较占内存空间。因此往往我们使用更多的是 QXmlStreamReader ,它是 Qt 中读取 XML 文档最快并且最为简单的方式。

2. QXmlStreamReader优点
(1)QXmlStreamReader 适用于诸如查找 XML 文档中的要给给定的 标记符 出现的次数,
(2)读取内存容纳不下的特大文件
(3)组装定制的数据结构以反映 XML 文档的内容

3. QXmlStreamReader 工作方式
QXmlStreamReader 根据下图中的 记号(token) 来工作。每次只需要调用 readNext() 函数, 下一个记号就会被读取并成为当前的记号。当前的记号的属性取决于 记号 的类型,可以使用该表格中列车的 getter() 函数读取当前的记号。


记号类型 示例 getter 函数
StartDocument N/A isStandaloneDocument()
EndDocument N/A isStandaloneDocument
StartElement <item> namespaceUri(),name(),attributes(),namespaceDeclarations()
EndElement </item> namespaceUri(),name()
Characters AT&amp;T text(),isWhitespace(),isCDATA()
Comment <! i–fix –> text()
DTD <!DOCTYPE..> text(),notationDeclarations(),entityDeclarations()
EntityReference &trade; name(),text()
ProcessingInstruction <?alert?> processingInstructionTarget(),processingInstructionData()
Invalid
&amp<
error(),errorstring()

QXmlStreamReader 的记号


4. QXmlStreamReader 来读取如下 XML 文件

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

——————————- XmlStreamReader.h 文件 —————————–

#ifndef XMLSTREAMREADER_H
#define XMLSTREAMREADER_H
#include <QString>
#include <QXmlStreamReader>
#include <QFile>
#include <QDebug>
#include <QMultiMap>
#include <QXmlStreamAttribute>

class XmlStreamReader
{
public:
    XmlStreamReader();
    ~XmlStreamReader();

    bool xmlStreamReaderFile(const QString fileName);

protected:
    QMultiMap<QString, QString> m_termMap; //存放标签的属性值
};

#endif // XMLSTREAMREADER_H

——————————- XmlStreamReader.cpp 文件 —————————–

#include "xmlstreamreader.h"

XmlStreamReader::XmlStreamReader()
{
}

XmlStreamReader::~XmlStreamReader()
{
}

bool XmlStreamReader::xmlStreamReaderFile(const QString fileName)
{
    if(true == fileName.isEmpty() || 0 == fileName.length())
    {
        qDebug()<<"Error: fileName is empty .";
        return false;
    }

    QFile file(fileName);
    if(!file.open(QFile::ReadOnly | QFile::Text))
    {
        //Qt提供了qPrintable()宏来执行将QString转换为const char *
        qDebug()<<"Error: Cannot read file"<<qPrintable(fileName)<<":"\
               <<qPrintable(file.errorString()); //打印设备最后一次出错的信息
        return false;
    }

    qDebug()<<"------------------------------";
    //定义要给QXmlStreamReader对象,同时将file作为QXmlStreamReader的输入设备
    QXmlStreamReader reader;
    reader.setDevice(&file);

    //file.close();
    //从输入流中读取下一个记号
    reader.readNext();
    while(!reader.atEnd())
    {
        if(reader.isStartElement())
        {
            if("bookindex" == reader.name())
            {
                //若标签为bookindex,则继续读取下一个记号
                reader.readNext();

                //读取文件的主体部分
                while(!reader.atEnd())
                {
                    //如果读取到了关闭标签,即</bookindex>,则结束
                    if(reader.isEndElement())
                    {
                        reader.readNext();
                        break;
                    }
                    //读取到新的顶级索引<entry>开始标签
                    if(reader.isStartElement())
                    {
                        /*++++++++++++++++++ 获取标签属性 +++++++++++++++++++*/
                        //获取person属性
                        QXmlStreamAttributes attributes = reader.attributes();
                        if(attributes.hasAttribute("term"))
                        {
                           // m_termMap["term"] = attributes.value("term").toString();
                            m_termMap.insert("term",attributes.value("term").toString());
                            qDebug()<<attributes.value("term").toString();
                        }
                        /*++++++++++++++++++++++++++++++++++++++++++++++++++*/
                        //若为<entry>开启标签,则读取条目文本数据
                        if("entry" == reader.name())
                        {
                            reader.readNext();
                            while(!reader.atEnd())
                            {
                                //若是关闭标签,则跳过该标签,同时跳出循环
                                if(reader.isEndElement())
                                {
                                    reader.readNext();
                                    break;
                                }

                                //若为开始标签,则可能情况有3种:<retry>,<page>和其他未知错误
                                if(reader.isStartElement())
                                {
                                    //若该记号为一个开始标签<retry>,则继续循环遍历
                                    if("entry" ==  reader.name())
                                    {
                                        //打印entry 标签对应的属性值
                                       attributes = reader.attributes();
                                        if(attributes.hasAttribute("term"))
                                        {
                                           // m_termMap["term"] = attributes.value("term").toString();
                                            m_termMap.insert("term",attributes.value("term").toString());
                                            qDebug()<<attributes.value("term").toString();
                                       }
                                        reader.readNext();
                                        while(!reader.atEnd())
                                        {
                                            //若是关闭标签,则跳过该标签,同时跳出循环
                                            if(reader.isEndElement())
                                            {
                                                reader.readNext();
                                                break;
                                            }

                                            if(reader.isStartElement())
                                            {
                                                if("page" == reader.name())
                                                {
                                                    QString page = reader.readElementText();
                                                    qDebug()<<page;
                                                    if(reader.isEndElement())
                                                    {
                                                        reader.readNext();
                                                    }
                                                }
                                            }else{
                                                reader.readNext();
                                            }
                                        }
                                    }else if("page" ==  reader.name()){
                                        QString page = reader.readElementText();
                                        qDebug()<<page;
                                        if(reader.isEndElement())
                                        {
                                            reader.readNext();
                                        }
                                    }else{
                                        //忽略不能识别的标签
                                    }
                                }else {
                                    reader.readNext();
                                }
                            }       //1.while

                        }else{
                            //忽略不能识别的标签
                        }
                    }else {
                        reader.readNext();
                    }
                }

            }else{
                reader.raiseError(QObject::tr("Not a bookindex file"));
                break;
            }

        }else{
            reader.readNext();
        }

    }

    qDebug()<<"================== Print attribute value Start ===================";
    QMultiMap<QString, QString>::iterator it = m_termMap.begin();
    while(it != m_termMap.end())
    {
        qDebug()<<it.value();
        ++it;
    }
    qDebug()<<"================== Print attribute value End ===================";

    //关闭设备文件
    file.close();
    return true;
}

——————————- main.cp 文件 —————————–

#include "widget.h"
#include "domxmlparse.h"
#include "xmlstreamreader.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    DomXmlParse parseXml;
    XmlStreamReader _reader;
    _reader.xmlStreamReaderFile("D:\\code\\untitled\\doc\\DomXml04.xml");
    return a.exec();
}

打印结果:

------------------------------
"sidebearings"
"10"
"34-35"
"307-308"
"subtraction"
"of picture"
"115"
"244"
"of vectors"
"9"
================== Print attribute value Start ===================
"of vectors"
"of picture"
"subtraction"
"sidebearings"
================== Print attribute value End ===================

猜你喜欢

转载自blog.csdn.net/lixiaogang_theanswer/article/details/80891735
今日推荐