QXmlStreamReader/QXmlStreamWriter实现Qt下xml文件读写

版权声明:若无来源注明, Techie亮博客文章均为原创。 转载请以连接形式标明本文标题和地址:
本文标题:QXmlStreamReader/QXmlStreamWriter实现Qt下xml文件读写     本文地址: http://techieliang.com/2017/12/714/

1. 介绍

帮助文档:QXmlStreamReaderQXmlStreamWriterhtml

除此之外读取时还须要使用QXmlStreamAttributesapp

1.1. QXml-Token标记类型

Constant Value Description
QXmlStreamReader::NoToken 0 The reader has not yet read anything.
QXmlStreamReader::Invalid 1 An error has occurred, reported in error() and errorString().
QXmlStreamReader::StartDocument 2 The reader reports the XML version number in documentVersion(), and the encoding as specified in the XML document in documentEncoding(). If the document is declared standalone, isStandaloneDocument() returns true; otherwise it returns false.
QXmlStreamReader::EndDocument 3 The reader reports the end of the document.
QXmlStreamReader::StartElement 4 The reader reports the start of an element with namespaceUri() and name(). Empty elements are also reported as StartElement, followed directly by EndElement. The convenience function readElementText() can be called to concatenate all content until the corresponding EndElement. Attributes are reported in attributes(), namespace declarations in namespaceDeclarations().
QXmlStreamReader::EndElement 5 The reader reports the end of an element with namespaceUri() and name().
QXmlStreamReader::Characters 6 The reader reports characters in text(). If the characters are all white-space, isWhitespace() returns true. If the characters stem from a CDATA section, isCDATA() returns true.
QXmlStreamReader::Comment 7 The reader reports a comment in text().
QXmlStreamReader::DTD 8 The reader reports a DTD in text(), notation declarations in notationDeclarations(), and entity declarations in entityDeclarations(). Details of the DTD declaration are reported in in dtdName(), dtdPublicId(), and dtdSystemId().
QXmlStreamReader::EntityReference 9 The reader reports an entity reference that could not be resolved. The name of the reference is reported in name(), the replacement text in text().
QXmlStreamReader::ProcessingInstruction 10 The reader reports a processing instruction in processingInstructionTarget() and processingInstructionData().

主要是用StartDocumentEndDocument文档开始结束,StartElementEndElement元素开始结束、Characters特征dom

1.2. 范例xml文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <bookmark href="http://qt-project.org/">
  3. <title>Qt Project</title>
  4. </bookmark>

第一行为StartDocument函数

bookmark、title为StartElement,/bookmark、/title为EndElementspa

href为attributes的一项,能够有多项,经过QXmlStreamAttributes::value获取后面的地址内容指针

Qt Project是title这个element的charcterscode

2. 写xml

  1. #include <QCoreApplication>
  2. #include <QFile>
  3. #include <QXmlStreamWriter>
  4. int main2(int argc, char *argv[]) {
  5. QCoreApplication a(argc, argv);
  6. QFile file("test.xml");
  7. if(file.open(QIODevice::WriteOnly | QIODevice::Text)) {
  8. QXmlStreamWriter stream(&file);
  9. stream.setAutoFormatting(true);
  10. stream.writeStartDocument();
  11. stream.writeStartElement("bookmark");
  12. stream.writeAttribute("href", "http://qt-project.org/");
  13. stream.writeTextElement("title", "Qt Project");
  14. stream.writeEndElement();
  15. stream.writeEndDocument();
  16. file.close();
  17. }
  18. return 0;
  19. }

写并不复杂,按顺序写便可,注意区分Attribute和Element,若是是一个小节用StartElement,若是是单行的相似于<title>Qt Project</title>能够直接用writeTextElement。orm

QXmlStreamWriter只是格式操做,并不提供文件操做,须要利用QFile创建文件并传递指针,也能够提供QString的指针,这样最终的xml信息会赋值到QString中。xml

3. 读xml

  1. #include <QCoreApplication>
  2. #include <QFile>
  3. #include <QXmlStreamReader>
  4. #include <QDebug>
  5. int main(int argc, char *argv[]) {
  6. QCoreApplication a(argc, argv);
  7. QFile file("test.xml");
  8. if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
  9. QXmlStreamReader xml(&file);
  10. while (!xml.atEnd() && !xml.hasError()) {//循环逐行读取
  11. QXmlStreamReader::TokenType token = xml.readNext();
  12. if(token == QXmlStreamReader::StartDocument)//文件开始跳过
  13. continue;
  14. if(token == QXmlStreamReader::StartElement) {//StartElement类型,主要针对bookmark和title
  15. if(xml.name() == "bookmark") {//bookmark读取,其下attributes有但只有一个
  16. qDebug()<<"StartElement-"<<xml.name();
  17. QXmlStreamAttributes attributes = xml.attributes();
  18. if(attributes.hasAttribute("href")) {//针对href的attribute作判断
  19. qDebug()<<"Attributes-"<<attributes.value("href");//返回值是QStringRef
  20. }
  21. //多个attributes在这里增长更多的if
  22. continue;
  23. }
  24. if(xml.name() == "title") {//title
  25. xml.readNext();//没有attributes,理应直接进入while,此处偷懒了
  26. if(xml.isCharacters()) //能够作Characters判断也能够直接用text
  27. qDebug()<<"title-Characters-"<<xml.text();
  28. }
  29. }
  30. }
  31. if (xml.hasError()) {
  32. //范例,判断枚举类型,写出错误字符串
  33. if(xml.error() == QXmlStreamReader::CustomError) {
  34. //能够直接写出错误字符串
  35. qDebug()<<"error:" <<xml.errorString();
  36. }
  37. }
  38. }
  39. return 0;
  40. }
  • 上述代码都没判断EndElement,不建议这样
  • 建议进入每个StartElement都直接开启一个while循环,直到循环到EndElement,从何保证对一个开头到结尾的完整操做,而不是像上述代码吧title放在和bookmark同级的循环内,并无标明title包含于bookmark的关系,这样容易致使错误。
  • 注意xml中每个<>括住的项都做为一个标记,都占用一次readNext,其开头均为name,其后可能有attribute及对应value。
  • 每两个<>XXX<>之间的XXX均做为一个Characters标记,也占用一次readNext,也就是上文中仍有未打印出的Character(“\n??? “换行符和四个空格、纯换行符):由于QXml以”\r”做为换行识别那么在先后两行的<><>之间还会余留一个\n;在title前的缩进也会当作一项Character。所以建议保证完整的包含关系并作好isXXX或者token枚举类型的判断以避免被干扰。

3.1. 其余

除上述xml操做之外,Qt还提供了Qt XML模块,用于更高级的xml操做,提供了高速及使用便利的操做函数(不可兼得呀)htm

高速的SAX方法读取,QXmlSimpleReader及相关类

使用便捷的DOM方式:QDomDocument及相关类

使用这两个方法,因为是用的非core模块,须要在pro中添加qt += xml

相关文章
相关标签/搜索