Skip to main content

Converting YAML to XML: How Keys Become Elements and Lists Become Repeated Tags

A practical guide to converting YAML to XML by hand or with a converter: keys map to elements, lists repeat the parent tag, and attributes vs child elements.

Published By Li Lei
#yaml #xml #data-conversion #developer-tools

Converting YAML to XML: How Keys Become Elements and Lists Become Repeated Tags

YAML is the format you reach for when a config file needs to be readable. XML is the format a surprising number of systems still demand: SOAP partners, Android resource files, Spring bean definitions, old .NET app.config files, RSS and Atom feeds. When those two worlds meet, you need a clean, predictable way to turn one into the other. The good news is that the mapping is mechanical once you know the three rules that govern it.

This guide walks through how YAML structures translate into XML, where the two formats disagree, and how to decide whether a piece of data should be an attribute or a child element. If you want to do it instantly without hand-writing tags, the YAML to XML converter does every step described here in your browser.

The Three Rules That Cover Most Conversions

Almost every YAML-to-XML conversion comes down to three rules:

  1. Each YAML key becomes an XML element. A mapping like name: Toolora becomes <name>Toolora</name>. The key is the tag name; the scalar value is the text content.
  2. Nested maps nest elements. When a value is itself a mapping, its keys become child elements. server: with a child port: 8080 becomes <server><port>8080</port></server>. This recurses to any depth, so a five-level-deep config produces five levels of nested tags.
  3. List items repeat the parent tag. XML has no array type. A YAML sequence does not become one tag with three children; it becomes the same tag written three times.

That third rule trips people up most often, so it's worth dwelling on. Given this YAML:

book:
  - title: A
  - title: B

The wrong instinct is to expect a wrapper like <books> containing two <book> elements. What you actually get is the book key repeated once per list item:

<book><title>A</title></book>
<book><title>B</title></book>

This is not a quirk of any one tool. It is the standard XML idiom for collections. RSS feeds repeat <item>, Atom feeds repeat <entry>, and a Spring config repeats <bean>. An empty list has nothing to repeat, so it collapses to a single self-closing <book/>.

A Worked Example

Here is a small but complete YAML document with a scalar, a nested map, and a list:

service:
  name: orders-api
  port: 8443
  endpoints:
    - path: /create
    - path: /cancel

Run it through the conversion and you get:

<service>
  <name>orders-api</name>
  <port>8443</port>
  <endpoints>
    <path>/create</path>
  </endpoints>
  <endpoints>
    <path>/cancel</path>
  </endpoints>
</service>

Trace the three rules through this output. service and its children follow rule one (key to element). The service map nests its keys, following rule two. And endpoints, being a list of two items, repeats the endpoints tag twice rather than producing an array, following rule three. Notice there is exactly one outer element, service, which matters for the next section.

The Single Root Element Rule

A well-formed XML document must have exactly one root element. YAML has no such constraint. A YAML file with two top-level keys is perfectly valid, but the XML equivalent is not, because two sibling tags at the top level give you a document with no single root.

The conversion handles this in a predictable way. When your YAML has exactly one top-level key, that key becomes the root automatically. note: hi becomes <note>hi</note> with nothing extra wrapped around it. When your YAML has zero or two-plus top-level keys, or the top level is itself a list or a single scalar, the content gets wrapped in a root element you name yourself. Pick something meaningful for the document, such as configuration, beans, or channel, rather than leaving the default generic wrapper.

Most config files have a single top-level key, so in practice you rarely touch the root name. It only earns its keep when you are stitching several top-level sections together into one document.

Attributes vs Child Elements

The most consequential design decision in any XML document is which data lives as an attribute and which lives as a child element. YAML has no native concept of attributes, so a convention is needed to express the difference. The common approach, and the one this converter uses, is a prefix: a key starting with @ becomes an attribute on its parent element instead of a child element.

So this YAML:

book:
  "@id": 7
  title: Deep Work

produces:

<book id="7"><title>Deep Work</title></book>

The @id key attached itself to the opening <book> tag, while title became a normal child. You usually quote the @ key in YAML so the parser does not get confused by the leading symbol.

Attributes carry a hard restriction: they can only hold scalar values, because XML attributes cannot contain nested markup. An @ key pointing at a map or a list has no valid XML representation, so it gets skipped rather than producing broken output. When you need both attributes and text content on the same element, pair the @ key with a #text key. This pattern is exactly how Android string resources are built:

string:
  "@name": app_title
  "#text": Toolora

becomes <string name="app_title">Toolora</string>.

So when should something be an attribute versus a child element? The rough heuristic, the same one schema designers have argued over for two decades: use attributes for metadata that identifies or qualifies the element (an id, a lang, a type), and child elements for the actual content. If a value might ever need to grow into structured data later, make it a child element from the start, because you cannot promote an attribute into a subtree without breaking every consumer.

When a Legacy System Forces Your Hand

I keep most of my service config in YAML for one selfish reason: clean diffs and inline comments. But twice this year a partner integration only accepted XML, and I was not about to maintain two parallel copies of the same payload by hand. My workflow now is to keep the YAML as the single source of truth and convert at the boundary, right before the call goes out.

That boundary is where escaping earns its place. Every value in the output is XML-escaped, so &, <, >, ", and ' become entities. A YAML value like note: "Tom & Jerry < cartoons" comes out as <note>Tom &amp; Jerry &lt; cartoons</note> rather than a corrupted document. This matters more than it sounds: an order note containing Q&A or a customer name with an ampersand is exactly the kind of thing that silently breaks a SOAP envelope at 2 a.m. if you assemble the XML by string concatenation. Element names get sanitized too, so a YAML key with a space or a colon cannot produce malformed markup.

A few things to watch for when a legacy system is on the receiving end. YAML comments do not survive the trip, because XML has no equivalent inline-comment concept in the object model; if you need them, keep the commented YAML as your source and treat the XML as a generated artifact. And if your attribute prefix in the tool does not match the prefix in your keys exactly, an intended attribute quietly becomes an ordinary element instead.

Round-Tripping and Related Conversions

One reason the @ and #text conventions are worth learning is that they round-trip. Convert XML the other direction with the XML to YAML converter, edit the readable YAML with comments and clean indentation, then bring it back here with the same prefix settings, and the element structure, attributes, and text survive intact. Keep both directions configured identically and the trip is lossless.

If XML is not actually your target and you only reached for it out of habit, two neighbors might fit better. The YAML to JSON converter is the right move when you are feeding a modern HTTP API, and JSON to XML covers the case where your data already lives as JSON. And once you have XML in hand, a quick pass through a formatter keeps the indentation honest before you commit it.

The mechanics never really change. Keys become elements, nested maps nest, lists repeat their tag, and you choose attributes for metadata and elements for content. Learn those four moves and converting between these formats stops being a chore and becomes a thirty-second step in your pipeline.


Made by Toolora · Updated 2026-06-13