JSON, YAML and XML: when do you use which?
Almost every configuration and every API in the IT world uses one of three text formats: JSON, YAML or XML. They store the same kind of data, but they look different and are handy for different things. In this article you’ll see the differences side by side, where you run into them and which mistakes you make most often. Handy if you’re writing a compose.yaml, editing a Home Assistant automation or want to read an API response.
The same data, three times
Say you want to describe a server with a name, an IP address and two ports. This is how that looks in each format.
JSON
{
"name": "nas",
"ip": "192.168.1.20",
"ports": [22, 443],
"active": true
}
YAML
name: nas
ip: 192.168.1.20
ports:
- 22
- 443
active: true
XML
<server>
<name>nas</name>
<ip>192.168.1.20</ip>
<ports>
<port>22</port>
<port>443</port>
</ports>
<active>true</active>
</server>
The differences at a glance
| JSON | YAML | XML | |
|---|---|---|---|
| Readable for people | Reasonable | Very good | Less, lots of text around it |
| Comments allowed | No | Yes, with # |
Yes, with <!-- --> |
| Structure | Braces and brackets | Indenting with spaces | Opening and closing tags |
| Typical place | APIs, app settings | Compose, Home Assistant, Ansible | RSS, SVG, sitemaps, older systems |
| Strictness | Strict: one comma too many gives an error | Sensitive to indentation | Strict: every tag must be closed properly |
JSON
JSON is the standard for data between programs. It has objects ({ } with "key": value), lists ([ ]) and a few types: text, number, true or false, and null. The rules are strict:
- Text is always in double quotation marks. Single quotes are not valid.
- There must be no comma after the last element.
- There’s no place for comments.
You make a JSON file that sits on one long line readable with the JSON Formatter. You can pull a specific piece out with the JSONPath Tester. On the command line you do that with jq:
jq . response.json # format neatly
jq '.ports[]' server.json # show all ports
python3 -m json.tool response.json # format without jq
YAML
YAML was made to be read and written by people. You use indenting with spaces instead of brackets and braces, and you can add comments. That’s why you see it in Docker Compose, Home Assistant, Ansible and many Kubernetes files.
The pitfalls:
- Tabs are not allowed. Use spaces, usually two per level. A wrongly indented line suddenly belongs to another part or causes an error.
- Ports as text. A value like
22:22may be read by some parsers as a number in base 60. So put port mappings in quotes:"22:22". Docker itself recommends this too. - Values that look like something else. In some YAML programs,
yes,no,onandoffare read as true and false. A version number such as3.10can become3.1. If in doubt, put the text in quotes. - A colon in text. A value that contains
:belongs in quotes.
Made a mistake and don’t know where? Paste your file into the YAML ↔ JSON tool: an indentation error will show up right away. If it’s in a compose file, the Compose Validator also finds duplicate ports and missing volumes.
XML
XML has been around the longest. It uses tags with a name, can also have attributes (<port protocol="tcp">22</port>) and is very precise. You come across it in RSS feeds, sitemaps, SVG images, Maven and Android settings, and in the description of virtual machines in libvirt.
- Every tag must be closed, and in the right order.
- Characters like
&and<in the text must be written as&and<.
With the XML Formatter you make XML readable and check that it’s valid. On the command line you can do that with xmllint --format file.xml (package libxml2-utils).
Converting between formats
JSON and YAML are very similar: almost every JSON file is also valid YAML. Converting from one to the other therefore usually goes without loss, except for comments, because JSON doesn’t have them. Use the YAML ↔ JSON tool for that. Going from XML to JSON is trickier, because XML has attributes and an order that JSON doesn’t.
Which format do you choose?
- An API or data between programs: JSON.
- A file that you edit by hand: YAML, because of the readability and the comments.
- The format is imposed on you by the program or the standard (RSS, SVG): XML.
And if you don’t get to choose? Then just use what the program expects. Most mistakes don’t come from choosing the format, but from a comma, a space or a quotation mark in the wrong place.