YAML to XML Converter
Two configuration formats a generation apart. Entries become elements, anchors are resolved first, and a key XML cannot use is corrected rather than emitted broken.
To convert YAML to XML, paste your file above. Each entry in the sequence becomes a row element inside a root element, both of which you name, with nested mappings flattened into dotted names first. Anchors and merge keys are resolved by the parser, and keys that are not legal XML element names are corrected with the original kept in an attribute.
Need to rename keys before you export? Open the app
The same job, two decades apart
XML was the configuration format of the 2000s and YAML is the configuration format of now, which means a lot of organisations have both and something in the middle has to translate.
The common case is a build or deployment system that still reads XML, being fed from a source of truth that has moved to YAML. The other is an integration: a partner's specification is XML, your service's configuration is YAML, and the same list of codes has to exist in both.
Either way the requirement is a document that parses on the first attempt, because the thing consuming it is old enough to be unforgiving and its error messages are byte offsets.
Tabular XML, said plainly
The output is one root element containing one element per entry, with one child per field. It is not a mirror of YAML's tree.
A nested mapping becomes resources.cpu as an element name rather than a resources element containing a cpu. That is a deliberate trade: a mirrored tree follows the whims of whoever last edited the YAML, and a fixed schema on the receiving end cannot accept a document whose shape changes.
If a faithfully nested XML tree is what the other end wants, that is a transform specific to their schema and hand-writing it will produce a better result than any generic converter.
Worked example
A config with a nested block:
- service: billing-api
replicas: 6
resources:
cpu: 500m
memory: 512Mi
cost centre: "01730"
With the root named services and the row element named service:
<?xml version="1.0" encoding="UTF-8"?>
<services>
<service>
<service>billing-api</service>
<replicas>6</replicas>
<resources.cpu name="resources.cpu">500m</resources.cpu>
<resources.memory name="resources.memory">512Mi</resources.memory>
<cost_centre name="cost centre">01730</cost_centre>
</service>
</services>
A dot is legal in an XML element name so the flattened names survive. cost centre is not, because of the space, so it became cost_centre with the original preserved in a name attribute.
The YAML shapes it reads
- A sequence of mappings is the ordinary case: one entry, one row.
- Several documents separated by
---become one row each when they are all mappings, which is the Kubernetes manifest shape and the useful reading of it. - A single mapping becomes a one-row table.
- Nested mappings flatten into dotted columns, so
resources.limits.cpuis one column. - A sequence of scalars becomes a single column called value, rather than an error.
- Anchors, aliases and merge keys are resolved by the parser before the table is built, so a manifest that reuses a block through
<<: *defaultscomes out with the merged values in place.
Escaping, and the values YAML lets through
Every value is escaped on the way out, including the apostrophe. YAML happily holds a raw ampersand or angle bracket in an unquoted scalar, and both are fatal in XML, so this is not a theoretical concern: a description field with R&D in it produces an unparseable document if written straight through.
An empty value or a YAML null becomes an empty element rather than a missing one, so every row element has the same children in the same order. A document whose shape varies per entry is the first thing a validator rejects.
A list inside an entry is written as JSON text inside its element. XML has no natural tabular form for a nested list, and inventing one would produce structure the recipient's schema does not describe.
Multi-document files, and one document out
A YAML file separated by --- holds several documents. XML holds exactly one root element, which means the two formats disagree about how many things a file is.
The resolution here is that all the documents become rows of one table under one root, with a note saying how many were combined. That is the reading that makes sense for the common case, a set of manifests or a set of records that a receiving system wants as one message.
If the receiving system genuinely wants one XML document per YAML document, split the file first. There is no option to emit several documents from one conversion, because a converter that produces multiple files quietly is worse than one that asks you to be explicit.
Elements or attributes
Child elements are the default and are the right choice for a config: values can be long, can contain anything once escaped, and read clearly in a diff.
Attribute mode writes <row service="billing-api" replicas="6"/>, one self-closing element per entry. It is much smaller and matches many older schemas, and it cannot carry a line break in a value. A config with a block scalar in it, which is any config with an embedded command or script, wants the element mode.
Frequently Asked Questions
Does it mirror my YAML nesting as nested XML?
No. It produces tabular XML with nested mappings flattened into dotted element names. Mirroring the tree gives you a document whose shape follows whoever last edited the YAML, which a fixed schema on the receiving end cannot accept.
Are anchors and merge keys resolved?
Yes, by the parser, before anything is written. A config that merges a defaults block into six entries produces six complete elements rather than six partial ones plus a defaults element the recipient does not expect.
What happens to a key with a space in it?
It becomes an underscore and the original spelling is kept in a name attribute on the element. YAML keys can be anything; XML element names cannot contain a space, start with a digit, or begin with the letters x, m, l in that order.
How is null represented?
As an empty element. Omitting it would make the document's shape vary from entry to entry, and a varying shape is exactly what a schema validator refuses.
What about a list inside an entry?
It is written as JSON text inside the element. XML has no natural tabular representation for a nested list, and inventing one produces structure the recipient's schema does not describe and cannot validate.
Does it generate a schema?
No. A DTD or XSD belongs to the specification you were given, and a generated one would look authoritative while disagreeing with it. What is guaranteed is a well-formed document with the element names you chose.
Feed the older system from the newer one
Well formed, anchors resolved, legal names, originals preserved.
Back to the converter