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>

 

 

 

 

下面是代码示例: ```cpp #include <QtCore/QCoreApplication> #include <QtCore/QFile> #include <QtCore/QXmlStreamReader> #include <QtCore/QXmlStreamWriter> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QString fileName = "example.ts"; QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { qDebug() << "Failed to open file."; return -1; } QXmlStreamReader xmlReader(&file); xmlReader.setNamespaceProcessing(false); QFile outputFile("modified.ts"); if (!outputFile.open(QFile::WriteOnly | QFile::Text)) { qDebug() << "Failed to open output file."; return -1; } QXmlStreamWriter xmlWriter(&outputFile); xmlWriter.setAutoFormatting(true); xmlWriter.writeStartDocument(); xmlWriter.writeStartElement("TS"); while (!xmlReader.atEnd()) { xmlReader.readNext(); if (xmlReader.isStartElement() && xmlReader.name() == "context") { xmlReader.readNext(); while (!(xmlReader.isEndElement() && xmlReader.name() == "context")) { if (xmlReader.isStartElement() && xmlReader.name() == "message") { QString source; QString translation; bool found = false; xmlReader.readNext(); while (!(xmlReader.isEndElement() && xmlReader.name() == "message")) { if (xmlReader.isStartElement() && xmlReader.name() == "source") { source = xmlReader.readElementText(); } else if (xmlReader.isStartElement() && xmlReader.name() == "translation") { translation = xmlReader.readElementText(); } if (source == "abc" && !translation.isEmpty()) { found = true; translation = "123"; } xmlReader.readNext(); } if (found) { xmlWriter.writeStartElement("message"); xmlWriter.writeStartElement("source"); xmlWriter.writeCharacters(source); xmlWriter.writeEndElement(); xmlWriter.writeStartElement("translation"); xmlWriter.writeCharacters(translation); xmlWriter.writeEndElement(); xmlWriter.writeEndElement(); } } xmlReader.readNext(); } } } xmlWriter.writeEndElement(); xmlWriter.writeEndDocument(); return a.exec(); } ``` 这段代码使用 `QXmlStreamReader` 解析 `.ts` 文件,并且使用 `QXmlStreamWriter` 写入修改后的 `.ts` 文件。对于每个 `context`,它会遍历所有的 `message`,并且查找 `source` 为 `abc` 的字段,如果找到了,就将其 `translation` 字段修改为 `123` 并且写入 `.ts` 文件。注意,这个代码没有处理错误情况,实际使用时可能需要加入相关的错误处理代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值