Network Automation

JSON vs XML vs YAML for Network Engineers: One Payload, Three Ways

JSON, XML and YAML - one interface config rendered three ways from a single Python dictionary
In: Network Automation, CCIE

Every network automation interface speaks in one of three data formats. RESTCONF uses JSON. NETCONF uses XML. Ansible and most human-authored config data use YAML. They all express the same thing - structured data - and once you see that they are three encodings of the same underlying model, the automation stack stops looking like a pile of unrelated tools and starts looking coherent.

This article takes one interface configuration and renders it as JSON, XML, and YAML side by side - all generated for real from one Python dictionary in the lab - and explains when each is used. It extends the network automation guide.

The key insight: same data, three encodings

A network device's configuration is structured data: an interface has a name, a description, an IP address (which itself has an address and a mask), an enabled flag. That structure - nested key-value pairs and lists - is the same regardless of how you write it down. JSON, XML, and YAML are three ways to write down the same structure.

In the lab, we started with one Python dictionary and rendered it three ways. Here is the dictionary as each format.

YAML - the human-authored source

interface:
  name: Loopback200
  description: DATA-FORMAT-DEMO
  ipv4:
    address: 172.30.1.1
    netmask: 255.255.255.0
  enabled: true

JSON - the RESTCONF payload

{
  "interface": {
    "name": "Loopback200",
    "description": "DATA-FORMAT-DEMO",
    "ipv4": {
      "address": "172.30.1.1",
      "netmask": "255.255.255.0"
    },
    "enabled": true
  }
}

XML - the NETCONF payload

<config>
  <interface>
    <name>Loopback200</name>
    <description>DATA-FORMAT-DEMO</description>
    <ipv4>
      <address>172.30.1.1</address>
      <netmask>255.255.255.0</netmask>
    </ipv4>
    <enabled>true</enabled>
  </interface>
</config>

Read all three and you see the same tree: an interface with a name, description, a nested ipv4 object, and an enabled flag. Only the syntax differs. A parser reads any of them into the same in-memory structure, which is exactly why you can convert freely between them - as we did, generating all three from one dict.

Where each is used, and why

YAML - for humans
Used by: Ansible playbooks/vars, most config-as-data files, this cluster's Jinja2 pipeline.
Strength: the most human-readable - minimal punctuation, indentation-based. You write and review it by hand.
Weakness: whitespace-sensitive; a stray indent is an error.
JSON - for APIs
Used by: RESTCONF, REST APIs, most modern web tooling.
Strength: universally supported, compact, native to JavaScript and easy in every language.
Weakness: no comments, more punctuation than YAML, no schema by itself.
XML - for NETCONF
Used by: NETCONF, SOAP, older enterprise systems.
Strength: namespaces, attributes, mature schema/validation (XSD), the format NETCONF was built on.
Weakness: verbose - the closing tags double the volume - and heavier to author by hand.

The mapping to network interfaces

The reason this matters is that the format follows the transport:

  • Automate a device with NETCONF? You are sending and receiving XML. The ncclient Python library builds and parses it.
  • Automate with RESTCONF? You are sending and receiving JSON (or XML - RESTCONF supports both, but JSON is the common choice). The requests library does the HTTP.
  • Author your config data for Ansible or a Jinja pipeline? You write YAML, and the tooling converts it to whatever the transport needs.

All three formats describe data structured according to a YANG model - the schema that defines what a valid interface configuration looks like. YANG is format-agnostic: the same YANG model can be encoded as XML (for NETCONF) or JSON (for RESTCONF). So the real picture is: YANG defines the structure; JSON and XML are how that structure travels; YAML is how you author it.

Converting between them in Python

Because they are the same data, conversion is trivial - load one format into a Python object, dump it as another:

import json, yaml
# YAML in
data = yaml.safe_load(open('interface.yml'))
# JSON out (for a RESTCONF PUT)
json_payload = json.dumps(data, indent=2)
# YAML back out
yaml_again = yaml.safe_dump(data)

XML is slightly more involved (libraries like xmltodict or lxml handle it), but the principle is identical: parse to a common structure, serialise to the target format. This is exactly what we did in the lab to produce all three from one dictionary. The format is a serialisation detail; the data is what matters.

The practical workflow

  1. Author in YAML. It is the most readable, and it is what you review in a pull request.
  2. Convert to the transport's format - JSON for RESTCONF, XML for NETCONF - programmatically, at push time.
  3. Parse the device's response (JSON or XML) back into a Python structure to verify or extract data.
  4. Never hand-author XML for NETCONF if you can avoid it. Build it from a structure; the verbosity makes hand-editing error-prone.

This workflow means you think in data, not in formats. You describe the interface once, and the tooling handles the encoding for whichever interface you happen to be using.

Key takeaways

  • JSON, XML, and YAML are three encodings of the same structured data. We proved it by rendering one Python dictionary as all three, identical in structure.
  • YAML for humans (Ansible, config-as-data, Jinja pipelines), JSON for APIs (RESTCONF, REST), XML for NETCONF (and legacy enterprise systems).
  • The format follows the transport: NETCONF = XML, RESTCONF = JSON, Ansible authoring = YAML.
  • All three describe data structured by a YANG model - YANG defines the structure, JSON/XML carry it, YAML authors it.
  • Conversion is trivial in Python because they are the same data - parse to a structure, serialise to the target format.
  • Think in data, not formats. Author in YAML, convert programmatically, never hand-author XML.

Next: Advanced EEM - Tcl, multi-event correlation, and EEM + Python. The full cluster index lives on the network automation pillar.

Written by
More from Ping Labz
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Ping Labz.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.