Qt第十八章 XML和Json格式解析
文章目录
- JSON
- 格式
- 解析
- Json生成
- 案例
- XML
- 简介
- 与HTML的区别
- 格式
- XML解析
- 流的方式
- DOM
- XML生成
- JSON与XML的区别比较
JSON
格式
JSON是一个标记符的序列。这套标记符包含六个构造字符、字符串、数字和三个字面名
-
- 六个构造字符
- 开始和结束数组:[ ]
- 开始和结束对象:{ }
- 名称分隔::(冒号)
- 值分隔,(逗号)
-
- 字符串用双引号包含
-
- 数字直接表示,不用引号包含
-
- 三个字面量
- true
- false
- null
- 对象由花括号组成
{"name":"yerennuo","age":18,"adress":{"country":"china","city":"wuxi"}}
- 数组由方括号组成
{"city":["无锡","南京","北京"]}
解析
void testJson()
{
QJsonDocument jdoc;
jdoc = QJsonDocument::fromJson(R"({ "Array" : [ true, 999, "string" ], "key" : "value", "null" : "null" })");
qDebug() << jdoc.toJson(); // 以普通方式打印
qDebug() << jdoc.toJson(QJsonDocument::Compact); // 压缩的方式,去掉了空白字符
}
Json生成
void creatJson()
{
QJsonDocument doc;
QJsonObject obj;
obj.insert("name", QJsonValue("张三"));
doc.setObject(obj);
qDebug() << doc.toJson(); // 默认indented方式打印
QJsonArray arr;
arr.push_back("123");
arr.push_back(true);
arr.push_back(12);
obj.insert("数组类型", arr);
doc.setObject(obj);
qDebug() << doc.toJson();
}
案例
拿到vesion的值,name的值,和ignoreFailures的值
void readJson()
{
QFile file("../../launch.json");
if (!file.open(QFile::ReadOnly | QFile::Text)) {
qDebug() << "文件有误";
return;
}
QJsonDocument doc;
doc = QJsonDocument::fromJson(file.readAll());
QJsonObject rootObj = doc.object(); // 拿到Json的根对象
if (rootObj.isEmpty()) {
qDebug() << "没获取到根对象";
return;
}
// 定位到version
QJsonValue val = rootObj.value("version");
qDebug() << val.toString();
// 定位到name
val = rootObj.value("configurations");
qDebug() << val[0]["name"].toString();
// 取得ingnoreFailures的值
qDebug() << val[0]["setupCommands"][0]["ignoreFailures"].toBool();
}
XML
简介
可扩展标记语言,标准通用标记语言Extensible Markup Language的子集,简称XML,是一种定义电子文档结构和描述其内容的国际标准语言,被设计用咯爱传输和存储数据。
XML的易于在任何应用程序中读写数据,这使XML很快成为数据交换的唯一公共语言,虽然不同的应用软件也支持其他的数据交换格式,但不久之后它们都将支持XML,那就意味着程序可以更容易的与Winows、Mac Os、Linux以及其他平台下产生的信息结合,然后可以很容易加载XML数据到程序中并分析它,并以XML格式输出结果
与HTML的区别
- 可扩展性方面:HTML不允许用户自定义它们自己的标识或属性,而XML可以
- 结构性方面:HTML不支持深层的结构描述,XML的文件结构嵌套可以复杂到任意程度,能表示面向对象的等级层次
- 可校验性方面:HTML没有提供规范文件以支持应用软件对HTML文件进行结构校验,而XML文件可以包括一个语法描述,使应用程序可以对文件进行结构校验
总之,XML是一个简单而又灵活的标准格式,为基于Web的应用提供了一个描述数据和交换数据的有效手段。但是XML并非是用来取代HTML的。HTML着重如何描述将文件显示在浏览器中,而XML着重描述如何将数据以结构化方式表示。
格式
为了避免错误,需要规定XML编码,或者将XML文档存为Unicode。
XML文件格式是纯文本格式,具体规则如下:
- 必须有声明语句
<?xml version="1.0" encoding="UTF-8"?>
- 注意大小写
- XML文档有且只有一个根元素
- 属性值使用引号
<property name="geometry">
<width>800</width>
- 所有的标记必须有相应的结束标记
- 所有空标记也必须被关闭
<connections/>
- 实体引用
实体引用 | 说明 | 详细 |
---|---|---|
< | < | 小于 |
> | > | 大于 |
& | & | 和号 |
' | ’ | 单引号 |
" | " | 引号 |
- XML中的注释
<!-- 这是一个注释 -->
- XML中,空格会被保留
HTML会把连续的空格合并为一个
而在XML中,空格不会被删减
- XML以LF存储换行
- XML元素是指从开始标签到结束标签的部分,元素可包含其他元素、文本或者两者的混合物,元素也可以拥有属性
XML解析
流的方式
void phraseXML()
{
QFile file("../../Widget.ui"); // 相对位置
if (!file.open(QFile::ReadOnly | QFile::Text)) {
qDebug() << "文件打开失败";
return;
}
QXmlStreamReader reader;
reader.setDevice(&file);
reader.readNext(); // 读取声明语句
qDebug() << "版本号" << reader.documentVersion()
<< "编码方式" << reader.documentEncoding();
while (!reader.atEnd()) {
QXmlStreamReader::TokenType type = reader.readNext();
switch (type) {
case QXmlStreamReader::StartElement:
if (reader.name().toString() == "ui")
qDebug() << reader.attributes().value("version");
else if (reader.name().toString() == "class") {
reader.readNext();
qDebug() << reader.text();
} else if (reader.name().toString() == "widget")
qDebug() << reader.attributes().value("class");
else
reader.skipCurrentElement(); // 跳过当前元素
break;
case QXmlStreamReader::Comment:
break;
default:
break;
}
}
}
DOM
需要先在cmake里添加Xml库
void phraseXML2()
{
QDomDocument doc;
QFile file("../../Widget.ui"); // 相对位置
if (!file.open(QFile::ReadOnly | QFile::Text)) {
qDebug() << "文件打开失败";
return;
}
doc.setContent(file.readAll()); // 以二叉树形式存储数据
qDebug() << doc.firstChild().nodeName() // 根节点键"xml"
<< doc.firstChild().nodeValue(); // 根节点值"version='1.0' encoding='UTF-8'"
QDomNodeList list = doc.elementsByTagName("property"); // 拿到所有名为property的节点
for (int i = 0; i < list.size(); i++) {
qDebug() << list.at(i).firstChild().nodeName(); //"rect" "string"
}
QDomElement root = doc.documentElement(); // 获取根标签
qDebug() << root.attribute("version"); //"4.0"
// 遍历
while (!root.isNull()) {
qDebug() << root.tagName();
QDomNodeList list = root.childNodes(); // 遍历一层子节点,如果要遍历全部,使用递归
if (!list.isEmpty()) {
for (int i = 0; i < list.size(); i++) {
root = list.at(i).toElement();
qDebug() << root.tagName();
}
}
root = root.nextSibling().toElement(); // 遍历兄弟节点
}
}
XML生成
- 流的方式写入
void createXML()
{
QXmlStreamWriter writer;
QFile file("../../test.xml");
if (!file.open(QFile::WriteOnly | QFile::Text)) {
qDebug() << "打开文件失败";
return;
}
writer.setDevice(&file);
writer.setAutoFormatting(true); // 设置自动格式
writer.writeStartDocument(); // 写入声明语句
writer.writeStartElement("ui"); // 写入根节点
writer.writeAttribute("version", "4.0");
writer.writeStartElement("class"); // 写入子标签
writer.writeEndElement();
writer.writeStartElement("widget");
writer.writeAttribute("class", "QWidegt");
writer.writeAttribute("name", "Widegt");
writer.writeEndElement();
writer.writeTextElement("class", "widget"); // 写入文本标签
writer.writeEndElement(); // 写结束标签
writer.writeEndDocument();
file.close();
}
- Dom
void createXML2()
{
QFile file("../../test2.xml");
if (!file.open(QFile::WriteOnly | QFile::Text)) {
qDebug() << "打开文件失败";
return;
}
QDomDocument doc;
// 添加根节点
QDomElement root = doc.createElement("ui");
doc.appendChild(root);
root.setAttribute("version", "4.0");
// 添加其他节点
QDomElement e1 = doc.createElement("class");
root.appendChild(e1);
e1.setAttribute("version", "123");
// 设置文本节点
QDomText t1 = doc.createTextNode("Widget");
e1.appendChild(t1);
QTextStream ts(&file);
doc.save(ts, 4, QDomNode::EncodingFromTextStream); // 4是指定的缩进
file.close();
}