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

相關文章
相關標籤/搜索