知识精讲
本课程介绍了API开发中最常用的三种数据编码格式JSON、XML、YAML,讲解了各自的特性、语法规则、Python操作方法,并通过实践实验和专家访谈分享了选型建议和学习技巧。
课程概述与核心概念
-
数据编码/序列化定义:也叫数据序列化,是将应用内的数据对象转换为可存储/可网络传输的文本格式的过程,反向转换为数据对象称为反序列化(解析),本质和电话语音转电信号再还原的原理一致。
-
三种核心格式定位 :三种都是基于文本、人类可读、机器可解析的结构化数据表示格式,是网络自动化领域最常用的数据格式。
-
格式选择原则:优先选择目标API/系统要求的格式;若支持多种格式,选择开发者最熟悉的格式即可。
-
通用结构特点 :三种格式都用于描述带属性的对象(用户、接口、VLAN等),绝大多数场景使用键值对表示数据,值可以是字符串、数字、布尔、列表、嵌套对象等类型。
- 🚩重点:每一种标点符号都有语法意义,错误的标点/缩进会导致解析失败,这是最常见的错误来源。
XML格式基础与Python操作
-
XML基础特性:全称可扩展标记语言,1998年发布,是三者中最古老的格式,类似HTML专注于数据存储而非展示,用于高度结构化数据的机器间通信,支持自定义标签。
-
XML语法规则:
-
整体为元素树结构,必须有且仅有一个根元素,支持嵌套子元素。
-
元素必须有开闭标签,无内容的元素可以使用自闭合标签;元素可以拥有属性,也可以嵌套子元素/值。
-
文件开头为XML序言,包含XML版本、编码类型等声明信息。
-
-
XML命名空间 :用于解决根元素重名导致的合并冲突,通过
xmlns属性定义唯一URI标识,支持默认命名空间(应用到所有元素)和显式命名空间(给元素加前缀标识所属空间)两种方式,显式命名空间适合元素来自多个不同空间的场景。 -
Python操作模块:
-
xml.etree.ElementTree:Python官方提供的轻量模块,通过parse()读取文件,getroot()获取根对象,可通过tag、attrib、find()/findall()/iter()遍历访问元素数据。 -
xmltodict:第三方模块,可以直接将XML转换为Python字典,使用体验和JSON一致,更简洁易用。
-
-
xmltodict常用技巧 :转换后XML属性会自动加上
@前缀,可以通过字符串替换或在parse()方法中指定attr_prefix=""参数去除前缀。-
代码示例(根据课堂图片):
去除属性@前缀的输出方法
print(json.dumps(xml, indent=4).replace("@", ""))
-
JSON格式基础与Python操作
-
JSON基础特性:全称JavaScript对象表示法,是XML的现代替代方案,基于JS但语言无关,开放标准,以大括号语法为特征,人类更易读写,机器更易解析生成,原生支持键值结构。
-
JSON支持的数据结构:
-
对象:使用大括号
{}包裹的键值对集合,对应Python字典。 -
数组:使用方括号
[]包裹的有序元素列表,对应Python列表。 -
两种结构可以互相嵌套,支持任意复杂度的结构化数据。
-
-
Python JSON模块核心方法:
-
json.dumps():接收Python字典/列表,将其转换为JSON格式字符串(序列化),支持indent可选参数实现格式化输出(美化打印)。 -
json.loads():接收JSON格式字符串,将其转换为合法的Python数据结构(反序列化)。🚩重点:JSON本身只是结构化文本,必须转换为Python原生数据结构才能进行操作,直接对JSON字符串执行字典操作会触发类型错误。
-
YAML格式基础与Python操作
-
YAML基础特性 :全称
YAML ain't markup language(递归式缩写),是三者中最新的格式,主打人类友好,主要用于配置文件,使用Python风格缩进表示嵌套,语法非常简洁。 -
YAML语法规则:
-
YAML是JSON的超集,任意合法JSON都是合法YAML;文件开头使用
---作为文档分隔符。 -
键值对格式:
键: 值,冒号后必须加空格,不需要引号包裹字符串。 -
列表元素使用
-(减号加空格)开头标识,不需要方括号和逗号。 -
嵌套结构通过缩进层次表示,不允许使用Tab缩进,通常使用2空格或4空格缩进,2空格更通用。
-
支持注释,使用
#开头标识注释内容。 -
🚩重点:缩进直接决定嵌套结构,错误的缩进会导致解析错误,必须统一缩进风格。
-
-
YAML与JSON对比(根据课堂图片):相同嵌套结构数据,YAML语法比JSON简洁很多:
YAML 示例 JSON 等价示例 yaml<br>---<br>inventory:<br> device:<br> - name: csrlkvl<br> version: 16.09<br> vendor: cisco<br> uptime: '2 days'<br> serial: XB96871<br> snmp:<br> - name: public<br> permission: ro<br> - name: private<br> permission: rw<br>json<br>{<br> "inventory": {<br> "device": [<br> {<br> "name": "csrlkvl",<br> "version": "16.09",<br> "vendor": "cisco",<br> "uptime": "2 days",<br> "serial": "XB96871",<br> "snmp": [<br> {"name": "public", "permission": "ro"},<br> {"name": "private", "permission": "rw"}<br> ]<br> }<br> ]<br> }<br>}<br> -
Python操作YAML:
-
使用第三方
PyYAML库,推荐使用yaml.safe_load()方法解析YAML:safe_load会禁止执行YAML中嵌入的可执行代码,避免安全漏洞,默认输出为Python字典。 -
解析为Python字典后,可以非常方便地转换为JSON格式。
-
JSON/YAML实验操作
-
YAML实验任务:从零创建YAML配置文件,逐步添加主机名、注释、OS版本、VLAN列表、SNMP配置、嵌套VLAN字典,验证Python可以正确读取并转换为JSON输出;对比了列表写法和嵌套字典写法,嵌套字典可读性更好。
-
JSON实验任务 :在Python中创建字典,通过
json.dumps()转换为JSON字符串,验证类型转换;手动创建JSON格式字符串,通过json.loads()转换为Python字典,验证转换后可以正常访问字典属性。- 🚩重点:API返回的数据默认是JSON字符串,必须通过反序列化转换为Python字典才能查询使用,这是网络自动化开发的核心流程。
专家经验分享
-
行业应用场景:所有支持API的网络设备(IOS XE、IOS XR、Nexus、ASA等)和Cisco平台(DNA Center、ACI、网络服务编排器)都使用JSON/XML作为API数据编码格式。
-
格式选型建议:旧的遗留应用/Java生态更多使用XML;现代云API和自动化工具更多使用JSON/YAML,Python处理JSON/YAML更简单。
-
学习技巧:
-
多练习从嵌套数据结构中提取目标值,因为实际API数据都是多层嵌套的,练习提取是掌握的关键。
-
使用可视化转换工具(如JSON转YAML在线网站),同一份数据在两种格式下对比查看,更容易理解结构差异。
-
💡 核心概念
-
序列化:将应用内的数据对象转换为可存储/可网络传输的文本格式的过程。
-
反序列化:将文本格式的编码数据转换为应用内可用数据对象的过程,也叫解析。
-
JSON模块核心方法:
-
序列化:
json.dumps(dict, indent=4)→str -
反序列化:
json.loads(json_str)→dict
-
-
YAML安全解析 :
yaml.safe_load(yaml_content)→dict
✨ 课堂金句
-
"Choosing the data encoding format may be a matter of preference, Mastering of its tools, or sometimes a requirement of the available APIs."
-
"the effort is worth it in the long run for you to be able to learn these skills."
-
"Practicing extracting that... is one big thing."
📝 推荐实验
-
实践任务:自行找公开API获取示例JSON数据,练习序列化/反序列化操作;完成课程配套的YAML/JSON实验,掌握Python双向转换流程。
-
工具推荐:使用在线JSON-YAML转换工具对比相同数据的不同格式表示,加深理解。
-
复习重点:掌握三种格式的语法差异、Python操作的核心方法、格式选型的原则,重点练习嵌套数据的解析和值提取。
📊 数据格式对比:YAML vs JSON
-
YAML:以缩进表示层级,支持注释和复杂数据结构,适合配置文件。示例:
--- inventory: csr1kv1: version: 16.09 vendor: cisco uptime: '2 days' serial: XB96871 snmp: - name: public permission: ro - name: private permission: rw -
JSON:使用大括号/方括号,键值对需双引号,无注释,适合数据交换。示例:
{ "inventory": { "device": [ { "name": "csr1kv1", "version": "16.09", "vendor": "cisco", "uptime": "2 days", "serial": "XB96871", "snmp": [ {"name": "public", "permission": "ro"}, {"name": "private", "permission": "rw"} ] } ] } }
🔍 Python数据处理实践
-
XML转JSON :使用
json.dumps()格式化输出,去除特殊字符(如@):print(json.dumps(xml, indent=4).replace("@", "")) -
YAML文件读取 :通过
yaml库解析YAML文件:import yaml with open('inventory.yml', 'r') as f: yaml_data = yaml.safe_load(f) # 安全加载YAML数据 -
JSON序列化/反序列化:
-
将字典转为JSON字符串:
json_str = json.dumps(facts, indent=4) -
访问JSON数据:
print(facts["hostname"])→ 输出csr1kv1
-
📋 网络设备信息示例(嵌套字典结构)
| 设备属性 | 示例值 | 说明 |
|---|---|---|
hostname |
csr1kv1 |
设备名称 |
os_version |
16.09 |
操作系统版本 |
snmp_config |
{"ro": "public", "rw": "private"} |
SNMP读写社区字符串 |
interfaces |
[{"name": "Gig0/4", "ip_addr": "10.254.0.1"}] |
接口配置列表 |
⚠️ 注意事项
-
YAML依赖严格缩进(通常2空格),不支持制表符
-
JSON键名必须用双引号,字符串值需用双引号包裹
-
Python中处理JSON/YAML时需注意数据类型转换(如
dict与str)