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>

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM