QT学习(6):JSON和XML

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();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值