Files
workspace/cpp/JsonParse/Json.md
e2hang ebcee63b7c New
2026-01-09 00:05:37 +08:00

357 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
**JSON**(全称 **J**ava**S**cript **O**bject **N**otation是一种轻量级的**数据交换格式**
简单来说JSON 就是一种**文本格式**,用来在不同的程序、不同的编程语言、或者客户端与服务器之间传递数据。虽然它的名字里带有 "JavaScript",但它其实是**独立于语言**的。几乎所有的现代编程语言C++, Python, Java, Go 等)都支持解析和生成 JSON。
---
### 1. JSON 的核心结构
JSON 的结构非常简单,只有两种基本结构:
1. **对象 (Object)**:无序的键值对集合(类似于 C++ 的 `std::map` 或 Python 的 `dict`)。
2. **数组 (Array)**:有序的值的列表(类似于 C++ 的 `std::vector` 或 Python 的 `list`)。
### 2. JSON 的语法规则(非常严格!)
很多初学者容易把 JavaScript 对象字面量和 JSON 搞混JSON 的语法要严格得多:
1. **数据在键值对中**`"key": value`
2. **数据由逗号分隔**:最后一个元素后面**不能**有逗号(虽然部分解析器允许,但标准不允许)。
3. **花括号保存对象**`{ ... }`
4. **方括号保存数组**`[ ... ]`
5. **字符串必须用双引号**:这是最容易出错的地方。**必须是 `"`,不能是单引号 `'`**。Key也必须用双引号包围。
---
### 3. JSON 支持的数据类型
JSON 的值Value只能是以下 6 种数据类型:
| 类型 | 描述 | 示例 |
| :--- | :--- | :--- |
| **String** | 字符串 | `"Hello World"` (必须双引号) |
| **Number** | 数字 | `100`, `-5.5`, `3.14` (不分整型浮点) |
| **Boolean** | 布尔值 | `true`, `false` (全小写) |
| **Null** | 空值 | `null` (表示空) |
| **Object** | 对象 | `{"id": 1}` (嵌套结构) |
| **Array** | 数组 | `[1, 2, 3]` |
*注意JSON 不支持函数、日期通常转为字符串、undefined 或注释。*
---
### 4. 一个完整的 JSON 示例
假设我们要描述一个“程序员”的信息JSON 文件可能长这样:
```json
{
"name": "张三",
"age": 28,
"isEmployee": true,
"skills": ["C++", "Python", "Linux"],
"address": {
"city": "上海",
"street": "南京东路",
"zipcode": null
},
"projects": [
{
"name": "后台管理系统",
"status": "completed"
},
{
"name": "AI 助手",
"status": "developing"
}
]
}
```
**解析上面的内容:**
* 最外层是一个 **Object** `{}`
* `"name"` 是键,值是字符串 `"张三"`
* `"age"` 是键,值是数字 `28`
* `"skills"` 是键,值是一个 **Array** `[]`,里面包含三个字符串。
* `"address"` 是键,值是一个嵌套的 **Object** `{}`
* `"zipcode"` 的值是 `null`
---
### 5. 常见应用场景
1. **前后端通信**
* 前端(网页/App向服务器请求用户数据服务器查询数据库后将数据组装成 JSON 格式返回给前端。
2. **配置文件**
* 很多软件使用 `.json` 文件来存储配置(如 VS Code 的 `settings.json`)。
3. **数据存储**
* NoSQL 数据库(如 MongoDB直接以类似 JSON 的格式BSON存储数据。
### 6. JSON 与 C++ (结合你上一个问题)
在 C++ 中,标准库没有内置 JSON 解析器,通常使用第三方库(最著名的是 `nlohmann/json`)。
JSON 和 `std::variant` 的关系非常紧密。因为 JSON 的值可能是数字、字符串、布尔值等多种类型中的一种,**解析 JSON 的底层实现往往就是基于 `std::variant` 或者类似的联合体机制。**
例如,一个简易的 JSON Value 类在 C++ 中可能这样定义:
```cpp
#include <variant>
#include <string>
#include <vector>
#include <map>
struct JsonValue; // 前向声明
// 定义 JSON 支持的类型
using JsonVariant = std::variant<
std::nullptr_t,
bool,
double,
std::string,
std::vector<JsonValue>, // 数组
std::map<std::string, JsonValue> // 对象
>;
struct JsonValue {
JsonVariant value;
};
```
### 总结
* **JSON** 是互联网上最通用的数据快递包装。
* **语法**大括号包对象方括号包数组Key 必须双引号。
* **优点**:人眼看得懂,机器好解析,体积小。
*
为了让你全面理解 JSON我把例子分成了**基础语法**、**常见结构**和**真实场景**三个类别。
### 第一类:基础语法演示
这些例子展示了 JSON 支持的最基本数据类型。
#### 1. 最简单的键值对 (Flat Object)
这是最基础的形式,类似于一个简单的字典。
```json
{
"username": "admin",
"timeout": 5000,
"isEnabled": true,
"description": null
}
```
#### 2. 纯数组 (Array)
JSON 也可以仅仅是一个数组,不包含最外层的键。
```json
[
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday"
]
```
#### 3. 各种数字格式
JSON 不区分整数和浮点数,统一为 Number。
```json
{
"integer": 42,
"float": 3.14159,
"negative": -10,
"exponent": 2.5e-3
}
```
---
### 第二类:结构化与嵌套
这是 JSON 最强大的地方,可以无限套娃。
#### 4. 对象中包含数组
比如一个学生选修了多门课。
```json
{
"student_id": 1001,
"name": "李雷",
"courses": [
"高等数学",
"大学英语",
"计算机导论"
]
}
```
#### 5. 数组中包含对象
这是最常见的数据列表格式(例如商品列表)。
```json
[
{
"id": 1,
"product": "iPhone 15",
"price": 5999
},
{
"id": 2,
"product": "AirPods",
"price": 1299
},
{
"id": 3,
"product": "MacBook",
"price": 9999
}
]
```
---
### 第三类:真实开发场景
这些是你未来写代码时最常遇到的 JSON 格式。
#### 6. 配置文件 (VS Code 风格)
很多软件的 `settings.json` 就是这样写的。
```json
{
"editor.fontSize": 14,
"editor.fontFamily": "Consolas, 'Courier New', monospace",
"editor.tabSize": 4,
"files.autoSave": "afterDelay",
"workbench.colorTheme": "Default Dark+",
"git.confirmSync": false
}
```
#### 7. 天气 API 响应数据
当你调用天气接口(如 OpenWeatherMap返回的数据通常包含多层嵌套。
```json
{
"coord": {
"lon": 116.4,
"lat": 39.9
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "晴朗无云",
"icon": "01d"
}
],
"main": {
"temp": 25.5,
"feels_like": 26.1,
"humidity": 40
},
"wind": {
"speed": 3.5,
"deg": 210
},
"city": "Beijing"
}
```
#### 8. 电商订单信息
一个复杂的订单结构,包含用户信息、地址信息、商品列表(数组)和支付状态。
```json
{
"order_id": "ORD-20231024-001",
"timestamp": "2023-10-24T14:30:00Z",
"user": {
"id": 8848,
"name": "王富贵",
"vip_level": "gold"
},
"shipping_address": {
"province": "广东省",
"city": "深圳市",
"street": "深南大道100号",
"zip": "518000"
},
"items": [
{
"sku": "KB-001",
"name": "机械键盘",
"quantity": 1,
"price": 399.00
},
{
"sku": "MS-002",
"name": "无线鼠标",
"quantity": 2,
"price": 99.50
}
],
"payment": {
"method": "alipay",
"total": 598.00,
"status": "paid"
}
}
```
#### 9. 游戏存档数据
假设你写一个 RPG 游戏,存档可能长这样。
```json
{
"player": {
"name": "DragonSlayer",
"level": 45,
"hp": 2350,
"max_hp": 2500,
"position": {
"map_id": "dungeon_03",
"x": 120.5,
"y": 45.0,
"z": -10.0
}
},
"inventory": [
{"item_id": "sword_fire", "count": 1, "durability": 85},
{"item_id": "potion_health", "count": 15},
{"item_id": "key_gold", "count": 1}
],
"quests": {
"active": [101, 104],
"completed": [1, 2, 3, 4, 100]
}
}
```
#### 10. GeoJSON (地理信息)
这是一种专门用来描述地图数据的标准 JSON 格式。
```json
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "某公园"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
]
]
}
}
]
}
```
### 总结 JSON 的特点:
1. **极简**:只有 `{}``[]``:``,``""` 这几个符号。
2. **严格**
* Example 1 中的 Key (`"username"`) 必须带双引号。
* Example 5 数组里最后一个元素后面绝对不能加逗号。
3. **万能**无论是简单的配置还是复杂的3D游戏坐标都能塞进去。