• 22.QT-QXmlStreamReader解析,QXmlStreamWriter写入


    XML介绍

    XML 用于存储数据,数据的形式类似于树结构(参考: http://www.runoob.com/xml/)

    示例如下

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <note>
      <to>George</to>
      <from>John</from>
      <heading>Reminder</heading>
      <body>Don't forget the meeting!</body>
    </note>

    其中第一行是XML声明,定义XML版本(1.0)以及所使用的编码格式

    接下来的<note>,便是该文档的根元素

    剩下的<to>,<from>,<heading>,<body>便是<note>的子元素

     

    QXmlStreamReader

     常用函数:

    QStringRef documentEncoding();    //获取XML编码,如果XML声明中未指定,则返回NULL
    
    QStringRef documentVersion () ;   //获取XML版本,如果XML声明中未指定,则返回NULL
    
    
    bool  atEnd ();
                                 //如果读者一直读到XML文档的末尾,或者出现了错误,并且阅读被中止,那么返回true。否则,它将返回false。
                                 //读取XML内容,如果读到XML末尾,或者读取出错时,将返回true,否则返回false
                                 //当返回true时,可以通过error()判断是否读取出错
    
    Error  error () ;            //返回错误类型,如果未出错,将返回QXmlStreamReader::NoError(数值0)
    
     
    void raiseError ( constQString & message = QString() );
                              //主动上报错误,并填入message 错误信息(可以通过errorString()获取),可以使得下次调用atEnd()时,直接返回true值
    
    QString errorString();
                              //获取发生的错误信息
    
     
    void QXmlStreamReader::setDevice ( QIODevice *device );     
                              //设置QXmlStreamReader的解析设备,等价于QXmlStreamReader ( QIODevice *)构造函数
    
    TokenType readNext();     //读取一次记号,并返回该数据的标志位,也可以通过
    
    //常用标记如下所示:
    QXmlStreamReader::StartDocument      //文档开始位置,用来定义XML版本,编码等信息,
    QXmlStreamReader::StartElement      //元素开始位置
    QXmlStreamReader::EndElement        //元素结束位置
    //比如<firstname>Anna</firstname> //<firstname> </firstname>元素便是元素开始以及结束位置. //“Anna”信息可以通过readElementText()成员函数获取. QXmlStreamAttributes attributes(); //获取元素的属性 //比如<entry term="of pictures"> //通过attributes().value("term").toString()则可以得到元素值"of pictures"

    XML解析示例

    以解析G:/QT/in.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>

    代码如下所示:

    #include <QtGui>
    
    void ParseEntry(QXmlStreamReader* reader,QTreeWidgetItem* widget)       //递归函数,用来解析entry元素
    {
        QTreeWidgetItem *item =new QTreeWidgetItem(widget); //在widget下创建节点
        item->setText(0,reader->attributes().value("term").toString());
                             //获取entry元素的"term"值,并添加到第1列,比如"sidebearings"
        QString pages;
    
        while(!reader->atEnd())
        {
            QXmlStreamReader::TokenType type=reader->readNext();
            if(type==QXmlStreamReader::EndElement && reader->name()=="entry")  //如果遇到 </entry>,则表示解析完成
            {
                break;
            }
    
            if(type==QXmlStreamReader::StartElement)
           {
                if(reader->name()=="entry")
                        ParseEntry(reader,item);        //如果是entry子元素,则继续递归执行
    
                else if(reader->name()=="page")
                    pages=pages+reader->readElementText()+" ";  //如果是page,则获取文本信息
    
                else
                   reader->raiseError("Element Name Error ");     //是其它元素,则上报Error信息
           }
        }
        item->setText(1,pages); //添加页数到第二列
    }
    
    void readFile(QFile* File)
    {
        QXmlStreamReader* reader = new QXmlStreamReader(File);
        QTreeWidget* widget = new QTreeWidget();
    
        QStringList header;
        header<<"term"<<"page";
        widget->setHeaderLabels(header);
    
        while(!reader->atEnd())
        {
            QXmlStreamReader::TokenType type=reader->readNext();
            if(type==QXmlStreamReader::StartElement &&  reader->name()=="entry")
                ParseEntry(reader,widget->invisibleRootItem());   //开始解析"entry"元素里的内容
        }
    
        File->close();
        widget->show();
    
        if(reader->hasError())              //如果解析出错
        {
            QMessageBox::information(NULL,"Read","Read :"+reader->errorString());
        }
    }
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc,argv);
    
        QFile* File = new QFile("G:/QT/in.xml");
        if(!File->open(QFile::ReadOnly | QFile::Text))
        {
            QMessageBox::information(NULL,"Open","Open error!");
            return 0;
        }
    
        readFile(File);         //解析File
    
        a.exec();
    }

    效果:

     

    QXmlStreamWriter

    常用函数

    void    setAutoFormatting(bool enable)            //设置自动格式化文本,XML文本输出时,转化成容易读的形式,否则,就是一整行  
    void    setAutoFormattingIndent(int spacesOrTabs)//格式化时缩进值,默认4个空格位 
    void    setCodec(const char * codecName );    
                //设置编码格式,必须放在writeStartDocument()函数前面才起作用
    void writeStartDocument(); void writeEndDocument(); void writeStartElement(constQString & qualifiedName ); void writeEndElement() void writeAttribute( constQString & qualifiedName, const QString & value ); //写入元素的属性值 void writeTextElement( constQString & qualifiedName, const QString & text ); //写入文本元素,比如<page>10</page>等于writeTextElement("page","10");

    示例

    #include <QtGui>
    #include "widget.h"
    
    void WriteEntry(QXmlStreamWriter *writer,QString value,QStringList pages)
    {
        writer->writeStartElement("entry");
        writer->writeAttribute("term",value);
    
        foreach(QString page,pages)
            writer->writeTextElement("page",page);
    
        writer->writeEndElement();
    }
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QFile file("./out.xml");
        if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            QMessageBox::information(NULL,"Error","Write Error");
            return 0;
        }
    
        QXmlStreamWriter writer(&file);
        writer.setAutoFormatting(true);
    
        writer.writeStartDocument();
    
        WriteEntry(&writer,"sidebearings",QStringList()<<"10"<<"34-35"<<"307-308");
    
        writer.writeStartElement("entry");
        writer.writeAttribute("term","subtraction");
    
        WriteEntry(&writer,"of pictures",QStringList()<<"115"<<"34-35"<<"244");
        WriteEntry(&writer,"of vectors",QStringList()<<"9");
    
        writer.writeEndElement();
        writer.writeEndDocument();
    
        file.close();
    
        return 0;
    }

    实现

    <?xml version="1.0" encoding="UTF-8"?>
    
    <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>34-35</page>
            <page>244</page>
        </entry>
        <entry term="of vectors">
            <page>9</page>
        </entry>
    </entry>

     

  • 相关阅读:
    详解用em替换px
    js判断是否为ie浏览器
    nth-child()选择器小结
    HTML5之canvas
    MQTT-SN协议乱翻之消息格式
    MQTT-SN协议乱翻之简要介绍
    MQTT 3.1.1,值得升级的6个新特性
    MQTT 3.1协议非严肃反思录
    MQTT协议笔记之mqtt.io项目HTTP协议支持
    MQTT协议笔记之mqtt.io项目Websocket协议支持
  • 原文地址:https://www.cnblogs.com/lifexy/p/9111740.html
Copyright © 2020-2023  润新知