Qt 学习之路 2(62):保存 XML
Qt 学习之路 2(62):保存 XML
前面几章我们讨论了读取 XML 文档的三种方法。虽然各有千秋,但是 Qt 推荐的是使用QXmlStreamReader。与此同时,许多应用程序不仅需要读取 XML,还需要写入 XML。为此,Qt 同样提供了三种方法:
- 使用
QXmlStreamWriter; - 构造一个 DOM 树,然后掉其
save()函数; - 使用
QString手动生成 XML。
可以看出,无论我们使用哪种读取方式,这几种写入的方法都与此无关。这是因为 W3C 仅仅定义了如何处理 XML 文档,并没有给出如何生成 XML 文档的标准方法(尽管当我们使用 DOM 方式读取的时候,依旧可以使用同样的 DOM 树写入)。
如同 Qt 所推荐的,我们也推荐使用QXmlStreamWriter生成 XML 文档。这个类帮助我们做了很多工作,比如特殊字符的转义。接下来我们使用QXmlStreamWriter将前面几章使用的 XML 文档生成出来:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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 文档的输出。这个函数会写下
XHTML
|
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
一行。与writeStartDocument()相对应的是最后的writeEndDocument(),告诉QXmlStreamWriter,这个 XML 文档已经写完。下面我们拿出一段典型的代码:
|
1
2
3
4
|
xmlWriter.writeStartElement("entry");
xmlWriter.writeAttribute("term", "of vectors");
xmlWriter.writeTextElement("page", "9");
xmlWriter.writeEndElement();
|
显然,这里我们首先写下一个 entry 的开始标签,然后给这个标签一个属性 term,属性值是 of vectors。writeTextElement()函数则会输出一个仅包含文本内容的标签。最后写入这个标签的关闭标签。这段代码的输出结果就是:
XHTML
|
1
2
3
|
<entry term="of vectors">
<page>9</page>
</entry>
|
其余部分与此类似,这里不再赘述。这样,我们就输出了一个与前面章节所使用的相同的 XML 文档:
XHTML
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?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:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//!!! 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(),需要按需使用。
Qt 学习之路 2(62):保存 XML的更多相关文章
- Qt 学习之路 2(9):资源文件
Qt 学习之路 2(9):资源文件 豆子 2012年8月31日 Qt 学习之路 2 62条评论 上一章节中我们介绍了如何使用QAction添加动作.其中,我们使用QIcon加载了一张 png ...
- Qt 学习之路 2(60):使用 DOM 处理 XML
Qt 学习之路 2(60):使用 DOM 处理 XML 豆子 2013年8月3日 Qt 学习之路 2 9条评论 DOM 是由 W3C 提出的一种处理 XML 文档的标准接口.Qt 实现了 DO ...
- Qt 学习之路 2(61):使用 SAX 处理 XML
Qt 学习之路 2(61):使用 SAX 处理 XML 豆子 2013年8月13日 Qt 学习之路 2 没有评论 前面两章我们介绍了使用流和 DOM 的方式处理 XML 的相关内容,本章将介绍 ...
- Qt 学习之路 2(59):使用流处理 XML
Qt 学习之路 2(59):使用流处理 XML 豆子 2013年7月25日 Qt 学习之路 2 18条评论 本章开始我们将了解到如何使用 Qt 处理 XML 格式的文档. XML(eXtensible ...
- Qt 学习之路 2(66):访问网络(2)
Home / Qt 学习之路 2 / Qt 学习之路 2(66):访问网络(2) Qt 学习之路 2(66):访问网络(2) 豆子 2013年10月31日 Qt 学习之路 2 27条评论 上一 ...
- Qt 学习之路 2(63):使用 QJson 处理 JSON
Home / Qt 学习之路 2 / Qt 学习之路 2(63):使用 QJson 处理 JSON Qt 学习之路 2(63):使用 QJson 处理 JSON 豆子 2013年9月9日 Qt ...
- Qt 学习之路 2(51):布尔表达式树模型
Qt 学习之路 2(51):布尔表达式树模型 豆子 2013年5月15日 Qt 学习之路 2 17条评论 本章将会是自定义模型的最后一部分.原本打算结束这部分内容,不过实在不忍心放弃这个示例.来自于 ...
- 《Qt 学习之路 2》目录
<Qt 学习之路 2>目录 <Qt 学习之路 2>目录 豆子 2012年8月23日 Qt 学习之路 2 177条评论 <Qt 学习之路 2>目录 序 Qt ...
- Qt 学习之路 2(76):QML 和 QtQuick 2
Home / Qt 学习之路 2 / Qt 学习之路 2(76):QML 和 QtQuick 2 Qt 学习之路 2(76):QML 和 QtQuick 2 豆子 2013年12月18日 Qt ...
随机推荐
- History - BOM对象
History 对象 History 对象包含用户(在浏览器窗口中)访问过的 URL. History 对象是 window 对象的一部分,可通过 window.history 属性对其进行访问. 注 ...
- opennebula kvm 创建VM oned报错日志
Thu Jul :: [ReM][D]: Req: UID: VirtualMachineDeploy result SUCCESS, Thu Jul :: [TM][D]: Message rece ...
- QT编译时出现警告 Warning: Class Node implements the interface QGraphicsItem but does not list it in Q_INTERFACES. qobject_cast to QGraphicsItem will not work!
1.一定要将public QObject放在public QGraphicsItem的前面,并且在该类的定义中添加Q_OBJECT宏. class XXGraphicsItem : public QO ...
- BT下载的原理 和疑问
我心中有几个疑问,同时也搜索了点素材,肯能对理解问题有帮助. BT下载,即P2P下载,是一种不需要中心化服务器的下载,实现原理是,每个客户端在下载的时候也作为服务器. 我的疑问是,P2P各个节点是如何 ...
- 500 Internal Server Error
解决策略: 1.httpd.conf中,开启apache头信息自定义模块 2.htaccess文件,对这个域名的资源进行访问时,添加一个头信息 Header set Access-Control-Al ...
- MySQL中having与where
having与where区别: where中不可以用聚合函数(条件字段是未分组中的字段),having中可以用聚合函(条件字段是分组后字段).不过这里也很好理解,SQL语句在执行是先执行select ...
- TabbedPane标签美化式样自定义
JTabbedPane标签美化式样自定义 摘自:https://blog.csdn.net/yuanzihui/article/details/43936795 通过继承BasicTabbedPane ...
- js-简单的作业
作业 1 将课堂 偶数奇数和 猜数字游戏 电话银行转for循环 2 编写 “个人所得税计算器”函数 10000 计算个税的方法: 3500 以下免征 6500 3500 ~ 5000 部分 缴纳 3% ...
- javascript总结5:js常见的数据类型
1 Number 数字类型 :包含正数,负数,小数 十进制表示: var n1 =23; 十六进制表示法:从0-9,a(A)-f(F)表示数字.以0x开头. var n2 = 0x42 2 字符串数据 ...
- URAL 1141. RSA Attack(欧拉定理+扩展欧几里得+快速幂模)
题目链接 题意 : 给你n,e,c,并且知道me ≡ c (mod n),而且n = p*q,pq都为素数. 思路 : 这道题的确与题目名字很相符,是个RSA算法,目前地球上最重要的加密算法.RSA算 ...