Mental model
When two systems exchange data, they need a shared way to serialize structured information into text. The three formats you’ll see in network automation:
- JSON — JavaScript Object Notation. The de facto standard for REST APIs.
- YAML — YAML Ain’t Markup Language. Indentation-based. Reads almost like prose.
- XML — eXtensible Markup Language. Verbose, tag-based. Legacy but still very much alive in NETCONF and SOAP APIs.
All three describe the same kinds of things:
- Scalars — strings, numbers, booleans, null
- Lists / arrays — ordered sequence
- Maps / objects — key-value pairs (also called dictionaries / hashes)
The structure of your data is the same regardless of which format you serialize it as. Only the punctuation changes.
Same data, three syntaxes
JSON
{
"hostname": "R1",
"interfaces": [
{
"name": "GigabitEthernet0/0",
"ip": "10.0.0.1",
"mask": "255.255.255.0",
"enabled": true
},
{
"name": "GigabitEthernet0/1",
"ip": null,
"enabled": false
}
]
}
Properties of JSON:
- Curly braces
{}for objects, square brackets[]for arrays - String values must use double quotes
- No comments allowed
- No trailing commas allowed (until JSON5, but pure JSON forbids them)
- Strict spec — easy for machines, slightly annoying for humans
YAML
hostname: R1
interfaces:
- name: GigabitEthernet0/0
ip: 10.0.0.1
mask: 255.255.255.0
enabled: true
- name: GigabitEthernet0/1
ip: null
enabled: false
Properties of YAML:
- Indentation defines structure (spaces, not tabs)
- Quotes mostly optional —
R1and"R1"mean the same thing - Lists start with
- - Comments allowed with
# - Designed for humans to read and write
YAML is a strict superset of JSON. Every valid JSON document is also valid YAML. Lots of tools use this for flexibility — accept either.
XML
<device>
<hostname>R1</hostname>
<interfaces>
<interface>
<name>GigabitEthernet0/0</name>
<ip>10.0.0.1</ip>
<mask>255.255.255.0</mask>
<enabled>true</enabled>
</interface>
<interface>
<name>GigabitEthernet0/1</name>
<ip xsi:nil="true"/>
<enabled>false</enabled>
</interface>
</interfaces>
</device>
Properties of XML:
- Opening and closing tags for everything (
<tag>...</tag>) - Attributes on tags (
<interface name="Gi0/0">) - Comments via
<!-- ... --> - Verbose — every value has a paired closing tag
- Schemas (XSD) provide strict validation
Where you’ll meet each one
| Format | Where it’s used |
|---|---|
| JSON | REST APIs (RESTCONF, Meraki, DNA Center, Webex, any modern Cisco API), JavaScript apps, NoSQL databases, config files for some tools |
| YAML | Ansible playbooks + inventory, Kubernetes manifests, GitHub Actions / GitLab CI, Docker Compose, lots of static-site generators |
| XML | NETCONF (RFC 6241), SOAP APIs, older Cisco automation, Microsoft AD ecosystem |
For network engineers in 2026, the order of importance is roughly: JSON > YAML > XML. But you’ll touch all three.
Pitfalls per format
JSON
{
"hostname": "R1", // ← BAD: comments not allowed
"interfaces": [
{ "name": "Gi0/0", }, // ← BAD: trailing comma
], // ← BAD: trailing comma
}
Either of these breaks JSON parsing. If you need comments or trailing commas, use YAML.
YAML
hostname:R1 # ← BAD: missing space after colon
interfaces:
- name: Gi0/0 # ← BAD: tab used for indentation
- name: Gi0/1 # ← BAD: 2-space indent vs 4-space mixed
Indentation is part of the language. Always use spaces (most editors auto-convert tabs to spaces in .yml files). Stay consistent — 2 or 4 spaces, pick one and never mix.
YAML’s worst trap: implicit type coercion. version: 1.0 parses as a number 1.0. version: 1.10 also parses as 1.10 (a number) and stringifies as 1.1 — silently losing the .10. If you mean a string, quote it: version: "1.10".
XML
<interface name=Gi0/0> <!-- ← BAD: attribute value needs quotes -->
<interface name="Gi0/0"> <!-- ← good -->
<interface> <!-- forgot to close -->
Less ambiguous than YAML, but the verbosity makes it tedious to write by hand. In practice you generate XML programmatically from a template.
Quick conversion tools
When you need to translate between formats:
| From → To | Tool |
|---|---|
| JSON ↔ YAML | yq (CLI tool, works like jq for YAML) |
| JSON ↔ XML | Online converters, or Python: xmltodict |
| Python dict ↔ any | json.dumps(), yaml.dump(), xml.etree.ElementTree |
Example with Python:
import yaml, json
# Read YAML, dump JSON
with open("playbook.yml") as f:
data = yaml.safe_load(f)
print(json.dumps(data, indent=2))
Common mistakes
-
Mixing tabs and spaces in YAML. Some lines use tabs, others spaces. YAML parsers silently misinterpret. Configure your editor to always use spaces for
.yml. -
Forgetting to quote strings that look like numbers / booleans.
version: 010parses as octal in some YAML parsers.key: yesparses as booleantrue. Quote ambiguous values. -
Trailing commas in JSON. A constant source of
JSON parse errorissues. Use a linter (likejq -e .in CI) to catch them. -
XML namespace confusion. XML has namespaces (
xmlns:abc="...") that change the meaning of tags. Easy to miss when writing by hand. Generate XML from templates rather than typing it. -
Treating all three as interchangeable. Tools usually accept exactly one. RESTCONF expects JSON (or XML, depending on Accept header). Ansible expects YAML. NETCONF expects XML. Match what the consumer wants.
-
Putting secrets in plaintext. None of these formats encrypt anything. Use Ansible Vault (for YAML), encrypted Kubernetes secrets (for K8s YAML), or a separate secrets manager. Don’t commit
password: cisco123to Git.
Lab to try tonight
- Take the example JSON above. Convert it by hand to YAML and XML. Compare the line counts.
- Use
yq(or Python) to round-trip a file: YAML → JSON → YAML. Verify the structure survived. - Write a Python script that:
- Reads an Ansible inventory in YAML
- Adds a new host
- Writes it back out
- Send a
curlrequest to a REST API (e.g. a Cisco DevNet sandbox) withAccept: application/jsonand again withAccept: application/xml. Compare the responses. - Open a Kubernetes YAML manifest. Find the YAML scalars, lists, and maps. Identify any quoted strings — what would happen if they weren’t quoted?
Cheat strip
| Concept | Plain English |
|---|---|
| JSON | {}, [], strict, REST APIs |
| YAML | Indentation, comments allowed, Ansible / Kubernetes |
| XML | <tag>...</tag>, verbose, NETCONF / legacy |
| Scalars | strings, numbers, booleans, null |
| Lists / arrays | ordered sequence |
| Maps / objects | key-value pairs |
| JSON ⊂ YAML | All valid JSON is valid YAML |
| Tabs vs spaces | YAML wants spaces. Always. |
yq and jq | CLI tools for YAML and JSON manipulation |
| Secrets | None of these encrypt — use Vault / secrets manager separately |