Json解析:
XML 曾经是各种应用的配置和传输的首选方式。但是现在 XML 遇到了一个强劲的对手:JSON。
总体来说,JSON 的数据比 XML 更紧凑,在传输效率上也要优于 XML。不过 JSON 数据的层次化表达不及 XML。
JSON 的全称是 JavaScript Object Notation,与 JavaScript 密不可分。
JSON 文档其实就是一个 JavaScript 对象,因而也称为 JSON 对象,以大括号作为起止符,其实质是不排序的键值对,其中键要求是 string 类型,值可以是任意类型(以下依次是字符串、数组、对象)。
{
"encoding" : "UTF-8",
"plug-ins" : [
"python",
"c++",
"ruby"
],
"indent" : { "length" : 3, "use_space" : true }
}
Qt5 新增加六个相关类:QJsonArray、QJsonDocument、QJsonObject、QJsonObject::iterator 、QJsonParseError、QJsonValue
读:QJsonDocument::fromJson()可以由QByteArray对象构造一个QJsonDocument对象,用于我们的读写操作。
QString json("{"
"\"encoding\" : \"UTF-8\","
"\"plug-ins\" : ["
"\"python\","
"\"c++\","
"\"ruby\""
"],"
"\"indent\" : { \"length\" : 3, \"use_space\" : true }"
"}");
QJsonParseError error;
QJsonDocument jsonDocument = QJsonDocument::fromJson(json.toUtf8(), &error);
if (error.error == QJsonParseError::NoError) {
if (jsonDocument.isObject()) {
QVariantMap result = jsonDocument.toVariant().toMap();//转化为variant的map
qDebug() << "encoding:" << result["encoding"].toString();//map中对应的variant转为相应模式
qDebug() << "plugins:";
foreach (QVariant plugin, result["plug-ins"].toList()) {
qDebug() << "\t-" << plugin.toString();
}
QVariantMap nestedMap = result["indent"].toMap();
qDebug() << "length:" << nestedMap["length"].toInt();
qDebug() << "use_space:" << nestedMap["use_space"].toBool();
}
}
写:使用QJsonDocument::fromVariant()函数获取QJsonDocument对象。QJsonDocument也可以以二进制格式读取对象,比如QJsonDocument::fromBinaryData()和QJsonDocument::fromRawData()函数。当我们成功获取到QJsonDocument对象之后,可以使用toJson()生成 JSON 文档。
QVariantList people;
QVariantMap bob;
bob.insert("Name", "Bob");
bob.insert("Phonenumber", 123);
QVariantMap alice;
alice.insert("Name", "Alice");
alice.insert("Phonenumber", 321);
people << bob << alice;
QJsonDocument jsonDocument = QJsonDocument::fromVariant(people);
if (!jsonDocument.isNull()) {
qDebug() << jsonDocument.toJson();
}
XML解析:
针对 XML 的通用处理,Qt4 提供了 QtXml 模块;针对 XML 文档的 Schema 验证以及 XPath、XQuery 和 XSLT,Qt4 和 Qt5 则提供了 QtXmlPatterns 模块。Qt 提供了三种读取 XML 文档的方法:
**QXmlStreamReader:**一种快速的基于流的方式访问良格式 XML 文档,特别适合于实现一次解析器(所谓“一次解析器”,可以理解成我们只需读取文档一次,然后像一个遍历器从头到尾一次性处理 XML 文档,期间不会返回读取已经读取过的内容
DOM(Document Object Model):将整个 XML 文档读入内存,构建成一个树结构,允许程序在树结构上向前向后移动导航,这是与另外两种方式最大的区别,也就是允许实现多次解析器(对应于前面所说的一次解析器)。DOM 方式带来的问题是需要一次性将整个 XML 文档读入内存,因此会占用很大内存;
SAX(Simple API for XML):提供大量虚函数,以事件的形式处理 XML 文档。这种解析办法主要是由于历史原因提出的,为了解决 DOM 的内存占用提出的(在现代计算机上,这个一般已经不是问题了)。
在 Qt4 中,这三种方式都位于 QtXml 模块中。Qt5 则将QXmlStreamReader/QXmlStreamWriter移动到 QtCore 中,QtXml 则标记为“不再维护”,这已经充分表明了 Qt 的官方意向。
使用QXmlStreamReader是 Qt 中最快最方便的读取 XML 的方法。因为QXmlStreamReader使用了递增式的解析器,适合于在整个 XML 文档中查找给定的标签、读入无法放入内存的大文件以及处理 XML 的自定义数据。
<doc>
<quote>Einmal ist keinmal</quote>
</doc>
StartDocument
StartElement (name() == “doc”)
StartElement (name() == “quote”)
Characters (text() == “Einmal ist keinmal”)
EndElement (name() == “quote”)
EndElement (name() == “doc”)
EndDocument
**读:**QXmlStreamReader的readNext()函数调用,解析器都会读取下一个元素
while (!reader.atEnd()) {
if (reader.isEndElement()) {
reader.readNext();
break;
}
if (reader.isStartElement()) {
if (reader.name() == "entry") {
readEntryElement(treeWidget->invisibleRootItem());
} else {
skipUnknownElement();
}
} else {
reader.readNext();
}
}
**写:**QXmlStreamWriter
xmlWriter.writeStartDocument();//<?xml version=\"1.0\" encoding=\"UTF-8\"?>
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.writeEndElement();
xmlWriter.writeEndDocument();