JSON与YAML(一):格式详解

在日常开发中,数据序列化和配置管理几乎无处不在。YAML和JSON作为两种主流的数据交换格式,各有特色和适用场景。本文将从格式规范入手,深入解析这两种数据格式的特点。

一、JSON格式解析

JSON格式规范

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,基于JavaScript的对象字面量语法,但完全独立于编程语言。

文件后缀为.json

JSON语法规则

  • 数据结构是键值对
  • 键必须用双引号包裹
  • 值可以是任意 JSON 支持的数据类型
  • 键值对之间用逗号分隔
  • 对象用大括号 {},数组用方括号 []
  • 字符串只能用双引号,不能用单引号
  • 不支持注释
  • 不能有多余的逗号

基本数据类型

JSON支持六种基本数据类型:

1. 字符串(String)
{
    "name": "John Doe",
    "description": "这是一个包含中文的字符串",
    "escaped": "包含\"引号\"和\\反斜杠的字符串"
}
2. 数字(Number)
{
    "integer": 42,
    "negative": -17,
    "float": 3.14159,
    "scientific": 1.23e-4,
    "zero": 0
}
3. 布尔值(Boolean)
{
    "enabled": true,
    "disabled": false
}
4. 空值(null)
{
    "empty_value": null
}
5. 对象(Object)
{
    "person": {
        "name": "Alice",
        "age": 30,
        "address": {
            "city": "Beijing",
            "country": "China"
        }
    }
}
6. 数组(Array)
{
    "numbers": [1, 2, 3, 4, 5],
    "mixed": ["string", 42, true, null],
    "nested": [
        {"id": 1, "name": "Item 1"},
        {"id": 2, "name": "Item 2"}
    ]
}

JSON的优势与局限

优势:

  • 语法简单,容易读写
  • 生态好,几乎所有语言都支持
  • 传输体积小,效率高
  • 和 JavaScript 天然兼容

局限:

  • 不能写注释,配置文档化不方便
  • 类型有限,比如没有日期、二进制
  • 不支持引用和继承
  • 大型配置文件可读性较差

二、YAML格式深度解析

YAML格式规范

YAML(YAML Ain't Markup Language)是一种人类友好的数据序列化标准,设计目标是既容易被人类阅读,又容易被机器解析。

文件后缀为.yaml.yml

YAML语法规则

  • 使用缩进表示层级关系(通常为2个空格,不允许使用Tab)
  • 键值对通过冒号 : 分隔,冒号后需有空格
  • 列表项以短横线 - 开头,后跟空格
  • 字符串可不加引号,包含特殊字符时可用单引号或双引号
  • 支持注释,使用 # 表示
  • 支持多行字符串(| 保留换行,> 折叠换行)
  • 支持锚点(&)和引用(*
  • 支持合并键(<<
  • 支持多文档(用 --- 分隔)
  • 对缩进敏感,缩进不一致会导致解析错误

基本语法特性

1. 缩进表示层次结构
database:
  host: localhost
  port: 5432
  credentials:
    username: admin
    password: secret123
2. 列表表示
# 使用短横线表示列表项
fruits:
  - apple
  - banana
  - orange

# 或者使用行内格式
colors: [red, green, blue]

# 嵌套列表
shopping_list:
  - name: groceries
    items:
      - milk
      - bread
      - eggs
  - name: electronics
    items:
      - phone
      - laptop
3. 标量数据类型
# 字符串
name: John Doe
description: "包含特殊字符的字符串"
multiline: |
  这是一个多行字符串
  第二行内容
  第三行内容

folded_string: >
  这是一个折叠字符串,
  多行会被合并成一行,
  除非有空行。

# 数字
age: 30
price: 99.99
scientific: 1.23e-4

# 布尔值
enabled: true
disabled: false
yes_value: yes
no_value: no

# 空值
empty_value: null
tilde_null: ~

# 日期时间
date: 2024-01-15
datetime: 2024-01-15T10:30:00Z
4. 复杂数据结构
# 映射(字典)
person:
  name: Alice
  age: 25
  hobbies:
    - reading
    - swimming
  address:
    street: 123 Main St
    city: Beijing

# 锚点和引用
defaults: &default_settings
  timeout: 30
  retries: 3

development:
  <<: *default_settings
  debug: true

production:
  <<: *default_settings
  debug: false
  timeout: 60

YAML高级特性

1. 注释支持
# 这是一个注释
database:
  host: localhost  # 行尾注释
  port: 5432
  # 可以在任何地方添加注释
  name: mydb
2. 多文档支持
---
# 第一个文档
name: Document 1
type: config
---
# 第二个文档
name: Document 2
type: data
...
3. 类型标记
# 显式指定类型
version: !!str 1.2
count: !!int 100
enabled: !!bool true

YAML的优势与局限

优势:

  • 极佳的人类可读性
  • 支持注释和文档化
  • 支持复杂数据结构和引用
  • 多种数据类型支持
  • 适合配置文件和数据交换

局限:

  • 对缩进极其敏感,容易出错
  • 解析器实现复杂,速度略慢
  • 某些实现有安全隐患
  • 生态和普及度不如 JSON

三、YAML与JSON结构对比

JSON vs YAML

特性JSONYAML
层级结构大括号 {}、方括号 []缩进(空格)表示
必须用双引号通常不加引号,支持单双引号
注释不支持支持 # 注释
解析速度中等
数据类型基本类型有限支持更多类型(如日期、合并、锚点等)
可读性机器友好,结构清晰人类友好,格式灵活
典型用途数据交换、网络通信配置文件、文档化配置
多文档支持不支持支持 --- 分隔多个文档
复杂结构不支持锚点和引用支持锚点 & 和引用 *

小结:

实际开发中,配置文件推荐用 YAML,数据交换和接口通信还是首选 JSON。YAML 写起来更顺手,但要注意缩进和格式,JSON 则更适合机器处理和网络传输。当然最终选择那种,更重要的还是依照个人乃至团队的习惯。

参考链接: