XML to YAML Converter
Bring a legacy feed into something you can read. Records are found without an XPath, attributes become keys alongside elements, and the output is quoted where a YAML parser would misbehave.
To convert XML to YAML, paste your document above. The repeating record element is detected automatically, each record becomes a mapping in a YAML sequence with attributes and child elements as keys, nesting flattens with dot notation, and any value a YAML reader would coerce is quoted so it survives.
Want to drop fields before you generate the file? Open the app
Migrating away from XML, one file at a time
Nobody converts XML to YAML for fun. It happens during a migration: a build system, a deployment descriptor or an application config that has been XML since 2011 is being rewritten, and the values in the old file have to survive into the new one.
Doing it by hand is where the mistakes come from, because an XML config is verbose enough that a missed element is genuinely hard to spot in a review.
The second case is reading. An XML feed with two hundred records is nearly unreadable in a terminal; the same records as YAML are scannable, and that is often all you need before deciding what to do with them.
Finding the records without asking you for a path
The hard part of reading XML as a table is deciding what a row is. A document has one root, and somewhere inside it is a repeating element that represents a record. Most tools make you supply an XPath expression for it.
That is a reasonable design and a bad first experience: you have to open the file, understand its structure, and write an expression before you see anything. Here the repeating element is found by looking for the deepest element name that occurs many times as a sibling, which is the record element in essentially every real feed.
Element children become columns, attributes become columns too, and nesting inside a record flattens with dot notation. What the detection picked is stated under the result, so if it guessed wrong on an unusual document you can see that immediately rather than wondering why the row count looks odd.
Worked example
A product feed with attributes and child elements:
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product id="SKU-101" category="Audio">
<product_name>Wireless Mouse</product_name>
<unit_price>23.07</unit_price>
<in_stock>161</in_stock>
</product>
<product id="SKU-108" category="Accessories">
<product_name>27in Monitor</product_name>
<unit_price>140.33</unit_price>
<in_stock>0</in_stock>
</product>
</products>
And the YAML:
- id: SKU-101
category: Audio
product_name: Wireless Mouse
unit_price: 23.07
in_stock: 161
- id: SKU-108
category: Accessories
product_name: 27in Monitor
unit_price: 140.33
in_stock: 0
The two attributes became the first two keys, in the order XML wrote them, followed by the child elements. Nothing needed quoting in this example, which is what you want: bare scalars where they are safe and quotes only where a reader would coerce.
Attributes are data too
XML has two places to put a value and different specifications choose differently. <product id="SKU-101"> and <product><id>SKU-101</id></product> carry the same fact, and plenty of documents use both at once.
So attributes become columns alongside element children rather than being ignored. A converter that reads only child elements loses the identifier on the majority of real feeds, because the identifier is very often an attribute.
Where an attribute and a child element share a name, both survive as separate columns rather than one overwriting the other. It is rare, and when it happens losing one silently would be much worse than an extra column.
Quoting, going the other way
XML has no types at all: every value is text. YAML has aggressive type resolution. That combination means the conversion has to be careful in a way the reverse direction does not.
A product code of 01730 is unambiguously the string 01730 in XML, and unquoted in YAML it is the number 1730. A country code of no is unambiguously the string no in XML, and unquoted in YAML it is the boolean false. A date element is unambiguously text in XML and a timestamp in YAML.
All three are quoted, along with anything else a YAML 1.1 reader would resolve into a different type. Everything else stays bare, because a file where every value is quoted is a file nobody reads and readability is the reason to choose YAML.
The shape, and what does not carry over
- The output is a flat sequence of mappings, always. No top-level key and no grouping, because both are guesses about your consumer.
- Namespaces are stripped from names. A key spelled
ns:pricewould be a strange YAML key, and the prefix carries no meaning once the document is gone. - Comments and processing instructions do not survive. YAML has comments but there is nowhere sensible to put them.
- Mixed content where an element has both text and child elements is uncommon in data documents; the text is kept and the children become their own columns.
- Nothing is added to the file. No generated-by comment, which two competing converters insert into every YAML they write.
Frequently Asked Questions
Do I need to supply an XPath for the records?
No. The repeating record element is found from the document's own structure, by looking for the element name that occurs many times as a sibling. What it picked is stated under the result, so a wrong guess on an unusual document is visible rather than mysterious.
Are attributes included?
Yes, as keys alongside the child elements. Plenty of specifications put the identifier in an attribute, so a converter that reads only child elements loses the most important field on a lot of real feeds.
Why are some values quoted?
Because XML has no types and YAML has aggressive ones. A product code of 01730 is unambiguously a string in XML and becomes the number 1730 unquoted in YAML. Anything a YAML 1.1 reader would coerce is quoted; everything else stays bare.
What happens to namespaces?
The prefix is stripped from the name, so ns:price becomes price. A key with a colon in it is awkward in YAML, and once the document is gone the prefix carries no meaning that a config consumer can use.
How is nesting inside a record handled?
It flattens into dotted keys, so an address element with a city inside it becomes address.city. Past four levels the value is kept as text, because a config with six-part dotted keys is harder to read than the XML was.
Is a comment added to the output?
No. Nothing is inserted into your file. Two of the free converters in this space stamp a generated-by line into every YAML they produce, and only one of them offers a way to turn it off.
Bring the feed into this decade
Records found for you, attributes kept, quotes exactly where a parser needs them.
Back to the converter