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 |
