前面幾章咱們討論了讀取 XML 文檔的三種方法。雖然各有千秋,可是 Qt 推薦的是使用QXmlStreamReader
。與此同時,許多應用程序不只須要讀取 XML,還須要寫入 XML。爲此,Qt 一樣提供了三種方法:ide
QXmlStreamWriter
;save()
函數;QString
手動生成 XML。
能夠看出,不管咱們使用哪一種讀取方式,這幾種寫入的方法都與此無關。這是由於 W3C 僅僅定義瞭如何處理 XML 文檔,並無給出如何生成 XML 文檔的標準方法(儘管當咱們使用 DOM 方式讀取的時候,依舊可使用一樣的 DOM 樹寫入)。函數
如同 Qt 所推薦的,咱們也推薦使用QXmlStreamWriter
生成 XML 文檔。這個類幫助咱們作了不少工做,好比特殊字符的轉義。接下來咱們使用QXmlStreamWriter
將前面幾章使用的 XML 文檔生成出來:code
QFile file("bookindex.xml"); if (!file.open(QFile::WriteOnly | QFile::Text)) { qDebug() << "Error: Cannot write file: " << qPrintable(file.errorString()); return false; } QXmlStreamWriter xmlWriter(&file); xmlWriter.setAutoFormatting(true); xmlWriter.writeStartDocument(); xmlWriter.writeStartElement("bookindex"); xmlWriter.writeStartElement("entry"); xmlWriter.writeAttribute("term", "sidebearings"); xmlWriter.writeTextElement("page", "10"); xmlWriter.writeTextElement("page", "34-35"); xmlWriter.writeTextElement("page", "307-308"); xmlWriter.writeEndElement(); xmlWriter.writeStartElement("entry"); xmlWriter.writeAttribute("term", "subtraction"); xmlWriter.writeStartElement("entry"); xmlWriter.writeAttribute("term", "of pictures"); xmlWriter.writeTextElement("page", "115"); xmlWriter.writeTextElement("page", "224"); xmlWriter.writeEndElement(); xmlWriter.writeStartElement("entry"); xmlWriter.writeAttribute("term", "of vectors"); xmlWriter.writeTextElement("page", "9"); xmlWriter.writeEndElement(); xmlWriter.writeEndElement(); xmlWriter.writeEndDocument(); file.close(); if (file.error()) { qDebug() << "Error: Cannot write file: " << qPrintable(file.errorString()); return false; } // ...
首先,咱們以只寫方式建立一個文件。而後基於該文件咱們建立了QXmlStreamWriter
對象。setAutoFormatting()
函數告訴QXmlStreamWriter
要有格式輸出,也就是會有標籤的縮進。咱們也可使用QXmlStreamWriter::setAutoFormattingIndent()
設置每一個縮進所須要的空格數。接下來是一系列以 write 開始的函數。這些函數就是真正輸出時須要用到的。注意這些函數以 write 開始,有 Start 和 End 兩個對應的名字。正如其名字暗示那樣,一個用於寫入開始標籤,一個用於寫入結束標籤。writeStartDocument()
開始進行 XML 文檔的輸出。這個函數會寫下orm
<?xml version="1.0" encoding="UTF-8"?>
一行。與writeStartDocument()
相對應的是最後的writeEndDocument()
,告訴QXmlStreamWriter
,這個 XML 文檔已經寫完。下面咱們拿出一段典型的代碼:xml
xmlWriter.writeStartElement("entry"); xmlWriter.writeAttribute("term", "of vectors"); xmlWriter.writeTextElement("page", "9"); xmlWriter.writeEndElement();
顯然,這裏咱們首先寫下一個 entry 的開始標籤,而後給這個標籤一個屬性 term,屬性值是 of vectors。writeTextElement()
函數則會輸出一個僅包含文本內容的標籤。最後寫入這個標籤的關閉標籤。這段代碼的輸出結果就是:對象
<entry term="of vectors"> <page>9</page> </entry>
其他部分與此相似,這裏再也不贅述。這樣,咱們就輸出了一個與前面章節所使用的相同的 XML 文檔:文檔
<?xml version="1.0" encoding="UTF-8"?> <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>224 </entry> <entry term="of vectors"> <page>9</page> </entry> </entry> </bookindex>
儘管咱們推薦使用QXmlStreamWriter
生成 XML 文檔,可是若是如今已經有了 DOM 樹,顯然直接調用QDomDocument::save()
函數更爲方便。在某些狀況下,咱們須要手動生成 XML 文檔,好比經過QTextStream
:字符串
//!!! Qt4 QTextStream out(&file); out.setCodec("UTF-8"); out << "<doc>\n" << " <quote>" << Qt::escape(quoteText) << "</quote>\n" << " <translation>" << Qt::escape(translationText) << "</translation>\n" << "</doc>\n"; //!!! Qt5 QTextStream out(&file); out.setCodec("UTF-8"); out << "<doc>\n" << " <quote>" << quoteText.toHtmlEscaped() << "</quote>\n" << " <translation>" << translationText.toHtmlEscaped() << "</translation>\n" << "</doc>\n";
這種辦法是最原始的辦法:咱們直接除了字符串,把字符串拼接成 XML 文檔。須要注意的是,quoteText 和 translationText 都須要轉義,這是 XML 規範裏面要求的,須要將文本中的 <,> 以及 & 進行轉義。不過,轉義函數在 Qt4 中是Qt::escape()
,而 Qt5 中則是QString::toHtmlEscaped()
,須要按需使用。it