<返回更多

Json与XML实战

2020-07-16    
加入收藏

1.Json语法

JSON 语法是 JAVAScript 语法的子集。一个 json 对象包含了字符串、整数、浮点数、普通数组、对象、对象数组等。

{
"name": "qaa",
"age": 80,
"professional": {
"english": 4,
"putonghua": 2,
"computer": 3,
},
"languages": ["C++", "C"],
"phone": {
"number": "123456789",
"type": "home"
},
"books": [{
"name": "linux kernel development",
"price": 7.7
}, {
"name": "Linux server development",
"price": 8.0
}],
"vip": true,
"address": null
}

上面代码中,数组的表示"languages":["C++", "C"],数组用大括号表示。

数组里面也可以放对象进去。对象用{ }表示。

"books":[{

"name": "Linux kernel development",

"price": 7.7

},

{

"name": "Linux server development",

"price": 8.0

}

]

JSON 语法规则

JSON 语法是 JavaScript 对象表示语法的子集。

(1)数据在名称/值对中

(2)数据由逗号分隔

(3)大括号保存对象

(3)中括号保存数组

JSON 名称/值对

JSON 数据的书写格式是:名称/值对。名称在双引号,名称后面写一个冒号。

"name":"qaa"。

Json值类型:

(1)数字(整数或浮点数),如{ "age":30 }

(2)字符串(在双引号)

(3)bool值(true或false)

(4)数组(在中括号中),数组可包含多个对象。"sites" 是包含三个对象的数组。每个对象代表一条关于某个网站(name、url)的记录。

{

"sites":[

{"name":"json与xml学习","url":"www.toutiao.com"},

{"name":"google","url":"www.google.com"},

{"name":"头条","url":"www.toutiao.com"}

]

}

(5)对象(在大括号),如{"name":"json与xml学习","url":"www.toutiao.com"}

(6)Json可以设置为null值。{"address":null}

2.Jsoncpp安装

jsoncpp 是一个 c++封装的 json 包,跨平台支持 windows、linux、unix 等多系统。

jsoncpp 源码地址:https://github.com/open-source-parsers/jsonc

安装

apt-get install libjsoncpp-dev

库的头文件安装在/usr/include/jsoncpp 中,库 API 文档默认在/usr/share/doc/libjsoncpp-dev/jsoncpp-api-html/目录下。

#include <jsoncpp/json/json.h>
#include <IOStream>
#include <string>
#include "jsoncpp/json/json.h"
#include "jsoncpp/json/value.h"
#include "jsoncpp/json/writer.h"

using namespace std;

int  main()
{
	cout << "Hello World!" << endl;
  Json::Value  root;
  Json::FastWriter  fast;
  
  root["ModuleType"] = Json::Value(1);
  root["ModuleCode"] = Json::Value("China");
  
  cout<<fast.write(root)<<endl;
  
  Json::Value sub;
  sub["version"] = Json::Value("1.0");
  sub["city"] = Json::Value(root);
  fast.write(sub);
  
  cout<<sub.toStyledString()<<endl;
  
  return 0;
}

编译

g++ jsoncpp_test.c -o test -ljsoncpp

Jsoncpp 支持的值

jsoncpp 使用 Json::Value 对象来保存 JSON 串,Json::Value 对象可以表示如下数据类型:

Json与XML实战

 

检测保存的数据类型

bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;

基础数据类型的访问

const char* asCString() const;
JSONCPP_STRING asString() const;
Int asInt() const;
UInt asUInt() const;
Int64 asInt64() const;
UInt64 asUInt64() const;
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;

ValueType::arrayValue 和 ValueType::objectValue 数据类型的访问,操作方式很类似C++的 vector,可以使用数组风格或者迭代器风格来操作数据。

ArrayIndex size() const;
Value& operator[](ArrayIndex index);
Value& operator[](int index);
const Value& operator[](ArrayIndex index) const;
const Value& operator[](int index) const;
Value get(ArrayIndex index, const Value& defaultValue) const;
const_iterator begin() const;
const_iterator end() const;
iterator begin();
iterator end();

ValueType::objectValue 数据类型的访问,操作方式很类似 C++的 map

Value& operator[](const char* key);
const Value& operator[](const char* key) const;
Value& operator[](const JSONCPP_STRING& key);
const Value& operator[](const JSONCPP_STRING& key) const;
Value& operator[](const StaticString& key);
Value& operator[](const CppTL::ConstString& key);
const Value& operator[](const CppTL::ConstString& key) const;
Value get(const char* key, const Value& defaultValue) const;
Value get(const char* begin, const char* end, const Value& defaultValue) const;
Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
Value get(const CppTL::ConstString& key, const Value& defaultValue) const;

修改数据

如何修改 Json::Value 保存的数据:

Value(ValueType type = nullValue);
Value(Int value);
Value(UInt value);
Value(Int64 value);
Value(UInt64 value);
Value(double value);
Value(const char* value);
Value(const char* begin, const char* end);
Value(const StaticString& value);
Value(const JSONCPP_STRING& value);
Value(const CppTL::ConstString& value);
Value(bool value);
Value(const Value& other);
Value(Value&& other);

注意:对于Int、Uint、Int64、UInt64 等类型,注意类型。root["age"] = 80;默认为int类型,如root["age"] = (Json::Uint)80;强制转换类型。

若要将变量设置为Null,则使用root["address"] = Json::nullValue;

3.CJson编译安装

下载

git clone https://github.com/DaveGamble/cJSON.git

参考 Readme 进行编译

直接使用 cJSON.h 和 cJSON.c 加入到源文件。

cJSON 结构

Json与XML实战

 


Json与XML实战

 

next、prev用于遍历数组或对象链的前后向链表指针;child指向数组或对象的孩子节点,type是value的类型,valuestring 是字符串值,valueint是整数值,valuedouble是浮点数值,string是key的名字。

cJSON 支持的类型

Json与XML实战

 

valuestring,当类型为cJSON_String或cJSON_Raw时,value的值,type不符合是为NULL

valueint,当类型为cJSON_Number 时,value的值。

valuedouble,当类型为cJSON_NUmber 时,value 的值

string,代表 key,value 键值对中 key 的值

cJSON_Parse

函数:

功能:按照cJson结构体序列化整个数据包,并在堆中开辟一块内存存储cJSON结构体。

返回值:成功返回一个指向内存块中的cJSON的指针,失败返回NULL。

Json与XML实战

 

cJSON_Delete

Json与XML实战

 

功能:释放位于堆中cJSON结构体内存。

注意:使用cJSON_Parse()获取cJSON指针后,若不再使用,则需调用cJSON_Delete()对其释放,否则会导致内存泄漏。

cJSON_Print

Json与XML实战

 

功能:

把cJSON数据解析成JSON字符串,并在堆中开辟一块char*的内存空间存储JSON字符串。cJSON_PrintUnformatted()与 cJSON_Print()类似,只打印输出不带格式,只是一个字符串数据。

返回值:

返回一个char*指针指向位于堆中JSON字符串,失败返回NULL。

注意:可以把cJSON链表中所有的cJSON对象打印出来,但是需要手动释放资源。free(char *)。

cJSON_Version

Json与XML实战

 

功能:获取当前使用的 cJSON 库的版本号。

返回值:返回一个字符串数据。

cJSON_GetArrayItem

Json与XML实战

 

功能:

从object 的cJSON链表中寻找key为string的CJSON对象

返回值:

成功返回一个指向cJSON类型的结构体指针,失败返回NULL。

与 cJSON_GetObjectItem()类似的接口还有:

Json与XML实战

 


Json与XML实战

 

函数简介

Json与XML实战

 


Json与XML实战

 


Json与XML实战

 


Json与XML实战

 


Json与XML实战

 


Json与XML实战

 


Json与XML实战

 


Json与XML实战

 

4.XML简介

XML 是 Extensible Markup Language 的缩写,即可扩展标记语言。使用 XML 标记语言可以做到数据或数据结构在任何编程语言环境下的共享。

XML 和 HTML 的区别

(1)在 HTML 中不区分大小写,在 XML 中对大小写要求非常严格。

(2)HTML 使用固有的标记,而 XML 没有固有标记。

(3)HTML 用于显示页面,把数据和显示结合在一起,在页面中展示这些数据。而XML把页面内容的数据或结构与显示分开。

XML 的优点

1.搜索,XML中可以提取文档的中任何位置的数据。

2.显示,将数据的结构和数据的显示形式分开,根据需要使数据呈现出多种显示方式,如HTML、PDF 等格式。

3.数据交换,XML标记语法简单,能通过解析器在任何机器上解读。能够在各种计算机平台上使用,逐渐成为一种数据交换的语言。

XML 使用场景

XML 大多用于本地化场景。在网络传输中,解析速度比不上json,protobuf等协议。

文件配置

Android 的应用配置文件

Json与XML实战

 

Java 中的 pom.xml 应用 配置文件

Json与XML实战

 

Tomcat 中的 server.xml 应用 配置文件

Json与XML实战

 

如Android 和 QT 都使用 XML 来配置界面

Json与XML实战

 

QT 界面配置文件

Json与XML实战

 

Android 界面配置文件

Json与XML实战

 

游戏中的关卡,英雄等级,装备之类,显示框大小,颜色之类

Json与XML实战

 

XML 文档的组成

XML 文档也属于纯文本文件,该文档一般如下四部分组成:

(1)XML文档声明

(2)XML文档类型定义

(3)XML文档注释

(4)XML标识及其内容(主体)

前面3步都是可选:

<?xml version="1.0" encoding="UTF-8"?>
<!--XML 文档注释-->
<?xml:stylesheet type="text/xsl"href="stu.xsl"?>
<!--班级中学生的信息-->
<class>
<student>
<name>Jone</name>
<age>20</age>
</student>
</class>

XML 的语法规则

(1)结束标记不能忽略,在XML文档中必须有起始标记。

(2)区分大小写。开始标记和结束标记的大小写必须相同。

(3)正确嵌套包含

<b><i>This text is bold and italic</i></b>

正确嵌套的意思是:由于 <i> 元素是在 <b> 元素内打开的,那么它必须在 <b> 元素内关闭。

XML 文档的元素一般是由标记头、标记末和标记间的字符串数据构成,如下图所示:

Json与XML实战

 

XML 文档中的第一个元素被称为根元素,有且只有一个元素,其它元素就成为子元素,子元素必须正确嵌套在根元素中。若元素的值存在空格,那就必须将这些空格的原样解析出来。

在 XML 中,省略关闭标签是非法的。所有元素都必须有关闭标签:

<p>This is a paragraph</p>

<p>This is another paragraph</p>

(4)在 XML 中,XML 的属性值须加引号。请研究下面的两个 XML 文档。第一个是错误的,第二个是正确的:

Json与XML实战

 

在第一个文档中的错误是,note 元素中的 date 属性没有加引号。

实体

预定义实体表如下所示:

实体在XML文档的一般引用格式如下:

&实体名;

Json与XML实战

 

属性

属性是用来修饰某个元素,如:

<root>
  	<a   attribute="aa"> this  is  test</a>
  </root>

注意:

(1)属性值必须引用引号括起来,如: attribute1=“aa” 或 attribute3=‘aa' ;

(2)元素的属性以名和值成对出现

(3)修饰同一个元素的属性的属性名不能相同

(4)属性值不能包含“&”、“’”、“<”等字符。

如果你把字符 "<" 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。

会产生 XML 错误:

<message>if salary < 1000 then</message>

避免这个错误,请用一个实体引用来代替 "<" 字符,引用主要是针对一些特殊字符。

<message>if salary < 1000 then</message>

(5)XML 中编写注释的语法与 HTML 的语法很相似:

<!-- This is a comment -->

XML 树结构

XML文档是一种树结构,它从“根部”开始,然后扩展到“枝叶”。

<?xml version="1.0" encoding="utf-8"?>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

解释:

第一行是XML声明。它定义XML版本和所使用的编码(utf-8)。

下一行描述文档的根元素<note>接下来4行描述根的4个子元素(to,from,heading,body)。

最后一行定义根元素的结尾:</note>

XML 命名规则

(1)名称可以包含字母,数字以及其它字符

(2)名称不能以数字或标点符号开始

(3)不能以字符"xml"(或XML、Xml)开始

(4)名称不能包含空格

(5)可使用任何名称,没有保留的字符

(6)名称具有描述性

(7)名称应当比较简短,如<book_title>,而不是:<the_title_of_the_book>。

(8)避免 "-" 字符,否则会认为需要提取第一个单词。

(9)避免 "." 字符,否则会认为"name"是对象"first"的属性。

(10) 避免 ":" 字符,冒号会被认为命名空间来使用。

(11)XML 文档经常有一个对应的数据库,一般使用数据库的名称规则来命名XML文档的元素。

XML 属性

(1)XML元素可在开始标签中包含属性,类似HTML

(2)属性(Attribute)提供关于元素的额外信息

属性通常提供不属于数据组成部分的信息。文件类型与数据无关。

<file type="gif">computer.gif</file>

元素与属性

第一个表示sex是一个属性,第二个例子,sex是一个元素。两个 例子均可提供相同信息。

Json与XML实战

 


Json与XML实战

 

因使用属性而引起的一些问题:

(1)属性无法包含多个值(子元素可以)

(2)属性无法描述树结构(子元素可以)

尽量使用元素来描述数据。仅仅适用属性来提供与数据无关的信息,比如类似QT那样用属性标识类别及对象名。

Json与XML实战

 

(3)向元素分配ID引用。用于标识XML元素,起作用的方式与HTML中属性ID是一样。如下面这种情况。

这个id只是一个标识符,用于标识不同标签,并不是标签数据的组成部分。

Json与XML实战

 

5.TinyXml2 库使用

TinyXML2 安装

(1) 下载 tinyxml2

git clone https://github.com/leethomason/tinyxml2.git

(2)进入目录并编译

cd tinyxml2/

cmake .

make

(3)测试版本的准确性

./xmltest

如果是fail 0就说明正常。

Json与XML实战

 

(4)安装

make install

可以看到安装的路径

Json与XML实战

 

可以直接在工程引入 tinyxml2.h 和 tinyxml2.cpp 即可。

Tinyxml2 简介

TinyXML2 是简单实用的开源的 C++XML 文件解析库,可以很方便的应用到现有的项目之中。TinyXML2 解析器相对 TinyXML1 在代码上是完全重写,使其更适合于游戏开发中使用。它使用更少的内存,更快,并使用更少的内存分配。

由于 XML 的树状结构,TinyXML2 将 XML 的节点抽象为 XMLNode,XML 中除了把属性 key-value 抽象为 XMLAttribute 类型外,其余的都看作 XMLNode 的子类,首先将整个XML 文档抽象为 XMLDocument,将声明部分抽象为 XMLDeclaration,将注释抽象为XMLComment,将元素抽象为 XMLElement,将文本抽象为 XMLText。

节点、 元素、 属性、 值的关系

Json与XML实战

 


Json与XML实战

 


Json与XML实战

 

注意:元素一定是节点,节点不一定是元素。

API 用法

从本地文件读取 xml

tinyxml2::XMLDocument doc;
doc.LoadFile( "test.xml" );
std::cout << doc.ErrorID() << std::endl;

从内存中加载 xml

static const char* xml = "<element/>";
tinyxml2::XMLDocument doc;
doc.Parse( xml );
std::cout << doc.ErrorID() << std::endl;

6.XML检测工具

使用在线工具去检查XML在线代码格式化。检查是否正确。

XML 在线代码格式化 http://tool.oschina.net/codeformat/xml/。

本篇文章分析到这里,欢迎点赞,分享,收藏,关注

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>