Convert XML to CSV

Drop an XML file here

or paste it below — .xml, .rss, .config

Ranked by records multiplied by fields, because a table is both tall and wide.

Output options

Drop an XML file in and get a spreadsheet-ready CSV back. The hard part of this conversion is not the commas, it is deciding which element is a row - and the usual answer is a text box where you type a path and guess. Here the candidates are worked out from the document and listed with how many records and how many fields each one would produce, so you pick from real numbers. Columns are collected from every record rather than the first. Nothing is uploaded.

How to convert XML to CSV

  1. Drop an .xml file into the box above or paste the markup in. Nothing is uploaded either way.
  2. Press Convert to CSV. The record element is chosen for you and every other candidate is listed underneath with its numbers.
  3. If the top pick is not the table you wanted, choose another from the list — the CSV is rebuilt immediately.
  4. For Excel, pick the semicolon delimiter if your locale uses it and leave the byte order mark on.

The hard part is deciding what a row is

Commas are not the difficulty in this conversion. XML is a tree and a CSV is a rectangle, so something has to decide which level of the tree is a row — and most converters make that your problem. The best-equipped one we found offers a text box reading “use this path to identify starting node” and the advice that your XML “should be record oriented in order to get good results”. It never says what the options were.

This page works them out. Every element path is measured twice — how many times it occurs, and how many distinct fields it would contribute — and the candidates are ranked by the two multiplied together, because a table is both tall and wide. You see the list with the numbers and can override the pick.

Why counting occurrences alone is not enough

This sounds like a detail until you try it on an ordinary catalogue: three books, with four authors between them. There are more author elements than book elements, so a ranking that looks only at how often something occurs picks the authors and hands you a one-column list of names instead of a table of books.

CandidateRecordsFieldsRanked by occurrenceRanked by rows × fields
catalog/book35SecondFirst
catalog/book/author41FirstSecond

Elements that carry nothing but their own text are weighted down for the same reason: they are the cells of a table, not its rows.

A column has to mean the same thing on every row

Records repeat fields — a book with two authors, a product with three tags. The obvious way to handle that is to number them as you go, so the two-author book fills author.1 and author.2. Do it record by record and a book with one author fills a plain author column instead, and now the first author of a book is in one column on some rows and a different column on others. Sort the spreadsheet and the damage is permanent.

So the decision is made per column across the whole file: if any record repeats a field, that field is numbered on every record, and a book with one author fills author.1 with author.2 left empty. You can also join repeats into a single cell if you would rather have one column.

Columns come from every record, not the first one

The quick way to build a header is to read the first record and use its fields. It works until the schema has grown — the field added last year exists only on recent entries, is missing from record one, and vanishes from the output without a word. Here every record is read before the header is written, and the report says how many columns appeared after the first record and how many records were missing each one.

That last number is worth reading. An empty cell in a CSV cannot distinguish “this field was blank” from “this field was not there”, and the report is the only place the difference survives.

What happens to nesting and attributes

In the XMLColumn
A child element of the recordtitle
An attribute on the record@isbn
A child element inside a childprice.amount
An attribute on a nested elementprice.@currency
A child element that occurs twiceauthor.1, author.2

The @ on attributes is not decoration: an element may legally carry an attribute and a child element with the same name, and without the prefix one of the two would overwrite the other.

The CSV itself

Values containing the delimiter, a double quote, a line break or leading and trailing spaces are quoted as RFC 4180 requires, so a description with a line break in it stays one cell instead of splitting the row in half. Line endings are CRLF, which is what Excel expects, and the optional byte order mark is what tells Excel on Windows to read the file as UTF-8 rather than turning accented characters into pairs of symbols.

Next steps

If the XML is too irregular to be a table, XML to JSON keeps the nesting — and keeps repeating elements as arrays so the shape does not change between files. JSON to XML goes back the other way. Once you have a CSV, split CSV breaks a large one into pieces without cutting through a quoted field, and CSV to JSON converts it onward. All of them are on the data tools page.

Frequently asked questions

How does it know which element is a row?

It counts. Every element path in the document is measured on two axes - how many times it occurs and how many distinct fields it would contribute - and the candidates are ranked by the product, because a table is both tall and wide. Counting occurrences alone gets it wrong in a very ordinary case: a catalogue of three books with four authors between them has more author elements than book elements, so an occurrence-only ranking hands you a one-column list of names. The candidates are all listed with their numbers, so you can override the top pick in one click.

What happens to nested elements?

They become dotted column names. A price element carrying a currency attribute inside a book gives you price and price.@currency as separate columns, which keeps everything without needing a second file. Attributes on the record element itself are columns too, prefixed with @ so they cannot be confused with a child element of the same name.

A field appears twice in one record. Which column does it go in?

Both, numbered - author.1 and author.2 - and this is decided per column across the whole file, not per record. That distinction matters more than it sounds: if the numbering were decided record by record, a book with two authors would fill author.1 and author.2 while a book with one author filled a plain author column, and the same kind of value would land in different columns on different rows. Here a column means the same thing on every row. You can also join repeats into one cell with a separator instead.

Will a field that only shows up halfway down the file be kept?

Yes. Columns are collected from every record, not from the first one. Tools that read record one and treat its fields as the header silently drop anything that appears later - which is the field that was added to the schema last year and only exists on recent entries. The page reports how many columns turned up after the first record and how many records were missing each one.

Can I open the result in Excel directly?

Yes. Choose the semicolon delimiter if your Excel is set to a European locale, and leave the byte order mark on so Excel reads the file as UTF-8 rather than mangling accented characters. Values containing the delimiter, a quote or a line break are quoted per RFC 4180, so a description field with a line break in it stays one cell.

What if my XML is not really a table?

Then the result will not be a good one, and the candidate list usually shows it - a document with no element occurring more than once or twice has nothing table-shaped in it. Deeply irregular XML is better handled as JSON, where the nesting survives. Our XML to JSON page keeps it.

Why does a broken file get an error instead of a partial result?

Because XML is strict by specification: an unclosed tag or a bare ampersand makes the document not well-formed, and the parser must stop rather than guess. The line and column are shown so you can find it. A converter that presses on hands back a CSV that looks complete and silently ends wherever the fault was.

Is my file uploaded?

No. The document is parsed and the CSV is written inside your browser tab, so exports, feeds and configuration files never travel to a server. The only limit on size is your own device's memory.