qt读写xml文件

Qt使用XML模块,在.pro文件中添加 QT += xml

Qt 提供了三种读 XML 文档的方法:

QXmlStreamReader/QXmlStreamWriter:

一种快速的基于流的方式访问良格式 XML 文档特别适合于实现一次解析器(所谓“一次解析器”,可以理解成我们只需读取文档一次,然后像一个遍历器从头到尾一次性处理 XML 文档,期间不会有反复的情况,也就是不会读完第一个标签,然后读第二个,读完第二个又返回去读第一个,这是不允许的);

DOM(Document Object Model):

将整个 XML 文档读入内存,构建成一个树结构,允许程序在树结构上向前向后移动导航,这是与另外两种方式最大的区别,也就是允许实现多次解析器(对应于前面所说的一次解析器)。DOM 方式带来的问题是需要一次性将整个 XML 文档读入内存,因此会占用很大内存;

SAX(Simple API for XML):

提供大量虚函数,以事件的形式处理 XML 文档。这种解析办法主要是由于历史原因提出的,为了解决 DOM 的内存占用提出的(在现代计算机上,这个一般已经不是问题了).基本不使用了.

QXmlStreamReader/QXmlStreamWriter

#include <QXmlStreamWriter>

#include <QXmlStreamReader>

写操作

void writeStartDocument();

//写文档头,作用类似于创建一个xml文档,并在文档开头部分写入版本信息和编码信息默认为:

  <?xml version="1.0" encoding="UTF-8"?>

void writeEndDocument();

//当调用这个函数时,即表示文档信息写入完毕

void writeStartElement(const QString &qualifiedName);

//写入开始记号 比如<COMMAND>

void writeEndElement();

//写入结束记号 比如</COMMAND>

void writeTextElement(const QString &qualifiedNameconst QString &text);

//写入文本信息 <OBJECT>USER</OBJECT>

void writeAttribute(const QString &qualifiedNameconst QString &value);

//写入文本的属性   <USER NAME="root" PASSWORD="123456"/>

 

QFile file(fileName);
    if(file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QXmlStreamWriter writer(&file);
        writer.setAutoFormatting(true);
        writer.writeStartDocument();
        writer.writeStartElement("COMMAND");
        writer.writeTextElement("OBJECT", "USER");
        writer.writeTextElement("ACTION", "LOGIN");
        writer.writeStartElement("DATA");
        writer.writeStartElement("USER");
        writer.writeAttribute("NAME", "root");
        writer.writeAttribute("PASSWORD", "123456");
        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndElement();
writer.writeEndDocument();
        file.close();
    }
<?xml version="1.0" encoding="UTF-8"?>
<COMMAND>
    <OBJECT>USER</OBJECT>
    <ACTION>LOGIN</ACTION>
    <DATA>
        <USER NAME="root" PASSWORD="123456"/>
    </DATA>
</COMMAND>

读操作

 readNext(): 从xml输入流中读取下一个记号。

 name(): 记号的名称,即<名称></名称>

 isStartElement():判断当前已读取的记号是否为开始元素,开始元素即<>

注意:像上面的 <OBJECT>USER</OBJECT>也是

 isEndElement():判断当前已读取的记号是否为结束元素,结束元素即</>

 readElementText():读取当前记号对应的文本值,<>文本值</>

 atEnd():判断是否为文件结尾

QXmlStreamAttributes attributes() const; 获取含有属性节点的属性

inline bool hasAttribute(const QString &qualifiedName); //

QStringRef value(const QString &qualifiedName) const;//获取属性的值

int StreamParseXml::readXml()
{
    if(fileName.isEmpty()) return -2;
    QFile *file = new QFile(fileName);
    if(!file->open(QFile::ReadOnly | QFile::Text)) {
        QMessageBox::information(NULL, QString("title"), QString("open error!"));
        return -1;
    }
    reader = new QXmlStreamReader(file);
     while(!reader->atEnd() && !reader->hasError()) {
         QXmlStreamReader::TokenType token = reader->readNext();
         if(token == QXmlStreamReader::StartDocument) {
             continue;
         }
          if (reader->isStartElement() && reader->name() == "OBJECT") {
              QString elementText = reader->readElementText();
              if (elementText == "USER") {
                  parseUserInformation();
                  break;
              }
          }
     }
    if (reader->hasError()) {
        qDebug() << reader->errorString();
        //QMessageBox::information(NULL, QString("parseXML"), reader->errorString());
    }
    reader->clear();
    delete reader;
    reader = NULL;
    return 0;
} 
void StreamParseXml::parseUserInformation()
{
    QString elementString = getValue("ACTION");
    if (elementString == "LOGIN") {
        while(!reader->atEnd()) {
            reader->readNext();
            if (reader->name() == "USER") {
                QXmlStreamAttributes attributes = reader->attributes();
                if(attributes.hasAttribute("NAME")) {
                    qDebug() << "USER=" << attributes.value("NAME").toString();
                }
                if(attributes.hasAttribute("PASSWORD")) {
                    qDebug() << "PASSWORD=" << attributes.value("PASSWORD").toString();
                }
            }
        }
    }
}
QString StreamParseXml::getValue(const QString &name)
{
    while(!reader->atEnd()) {
        reader->readNext();
        if (reader->isStartElement() && reader->name() == name) {
            return reader->readElementText();
        }
    }
    return "";
}

QDomDocument

引用头文件

#include <QDomDocument>

QDomDocument类代表整个的XML文件。概念上讲:它是文档树的根节点,并提供了文档数据的基本访问方法。由于元素、文本节点、注释、指令执行等等不可能脱离一个文档的上下文,所以文档类也包含了需要用来创建这些对象的工厂方法

DOM类中最常使用的是QDomNode、QDomDocument、QDomElement和QDomText。

 QDomDocument::setContent()完成XML文档的设置,他从QFile对象中读取XML数据并检测XML文档的编码

写操作

结合QFileQTextStream类一起使用。

常用的函数:

QDomProcessingInstruction createProcessingInstruction(const QStringtargetconst QStringdata);//创建版本和编码格式

QDomNode appendChild(const QDomNodenewChild);//添加数据到节点

QDomElement createElement(const QStringtagName);//创建节点

QDomText createTextNode(const QStringdata);//创建节点的文本

QDomAttr createAttribute(const QStringname);//创建属性

QDomAttr setAttributeNode(const QDomAttrnewAttr);//节点关联属性

 void save(QTextStream&, intEncodingPolicy=QDomNode::EncodingFromDocumentconst;//把整个QDomDocumentQTextStream形式保存到本地文件。

int DomDocument::writeXml()
{
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return -2;
    QTextStream out(&file);
    QDomDocument doc;
    QDomText text;
    QDomElement element;
    QDomAttr attr;
    QDomProcessingInstruction instruction;
    instruction = doc.createProcessingInstruction( "xml", "version = \'1.0\' encoding=\'UTF-8\'" );
    doc.appendChild( instruction );
 
    QDomElement root = doc.createElement( "COMMAND" );
    doc.appendChild(root);
    element = doc.createElement( "OBJECT" );
    text = doc.createTextNode( "USER" );
    element.appendChild(text);
    root.appendChild(element);
 
    element = doc.createElement( "ACTION" );
    text = doc.createTextNode( "LOGIN" );
    element.appendChild(text);
    root.appendChild(element);
 
    element = doc.createElement( "DATA" );
    root.appendChild(element);
 
    QDomElement userElement = doc.createElement( "USERINFO" );
    attr = doc.createAttribute( "NAME" );
    attr.setValue("root");
    userElement.setAttributeNode(attr);
    attr = doc.createAttribute( "PASSWORD" );
    attr.setValue("123456");
    userElement.setAttributeNode(attr);
    element.appendChild(userElement);
 
    doc.save(out, 4);       //each line space of file is 4
    return 0;
}

读操作

结合QFile类一起使用。使用setContent函数进行关联。

bool setContent(QIODevicedevbool namespaceProcessingQString *errorMsg=nullptrint *errorLine=nullptrint *errorColumn=nullptr );QFileQDomDocument关联,从QFile对象中读取XML数据

QDomElement documentElement() const; //获取dom树的根标签

QString tagName() const;  //获取根/子标签的标签名字,对应于createElement函数的参数

 QString text() const; //获取根/子标签的文本,对应于createTextNode函数的参数

QDomNode firstChild() const;//根/子标签下的子标签

 QDomNode nextSibling() const; //下一个标签

bool isNull() const; //判断标签是否为空,用于是否标签到最后面结束了。

QDomElement toElement() const;  //把QDomNode 转换成QDomElement ,即基类转换成子类

bool hasAttribute(const QStringnameconst; //判断标签节点是否有属性

对应于createAttribute函数操作

QDomAttr attributeNode(const QStringname);//获取标签节点的属性

QString name() const;//获取标签节点的属性名称

QString value() const;//获取标签节点的属性值

int DomDocument::readXml()
{
    QDomDocument doc;
    QFile file(fileName);
    QString error = "";
    int row = 0, column = 0;
    if (!file.open(QIODevice::ReadOnly)) return -2;
 
    if(!doc.setContent(&file, false, &error, &row, &column)){
        qDebug() << "parse file failed:" << row << "---" << column <<":" <<error;
        file.close();
        return -1;
    }
 
    file.close();
    QDomElement root = doc.documentElement();
    QDomNode node = root.firstChild();    //得到COMMAND标签
    while(!node.isNull()) {
       QDomElement element = node.toElement(); // try to convert the node to an element.
       if(!element.isNull()) {
          qDebug()<<element.tagName() << ":" << element.text();
          QDomNode nodeson = element.firstChild(); //得到OBJECT标签
          while(!nodeson.isNull()) {
              QDomElement elementson = nodeson.toElement();
              if(!elementson.isNull()) {
                  qDebug()<< "---" <<elementson.tagName();
                  if (elementson.hasAttribute("NAME")) {
                      qDebug()<< "---" << "NAME=" << elementson.attributeNode("NAME").value();
                  }
                  if (elementson.hasAttribute("PASSWORD")) {
                      qDebug()<< "---" << "PASSWORD=" << elementson.attributeNode("PASSWORD").value();
                  }
              }
              nodeson = nodeson.nextSibling();
          }
       }
       node = node.nextSibling();
    }
    return 0;
}

  • 1
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值