【Qt筆記】保存 XML

前面幾章咱們討論了讀取 XML 文檔的三種方法。雖然各有千秋,可是 Qt 推薦的是使用QXmlStreamReader。與此同時,許多應用程序不只須要讀取 XML,還須要寫入 XML。爲此,Qt 一樣提供了三種方法:ide

  1. 使用QXmlStreamWriter
  2. 構造一個 DOM 樹,而後掉其save()函數;
  3. 使用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

相關文章
相關標籤/搜索