XML to CSV Converter
Paste XML or drop an .xml file, choose which element is a row, and download the CSV.
How to use
- Step 1Paste the XML or drop an .xml file. The converter looks for the element that repeats (product, item, row, record, entry) and takes each occurrence as one row.
- Step 2Check "Row element" if it guessed wrong, pick a delimiter (comma, semicolon for Excel in most of Europe, tab for pasting into a sheet), and decide whether attributes such as id="…" become columns.
- Step 3Copy the CSV or download data.csv. In Excel use Data › From Text/CSV rather than double-clicking the file, so accented characters, leading zeros and long numbers come through unchanged.
Where XML comes from
XML is the older of the two big data formats and still the one many systems speak: RSS and Atom feeds, sitemaps, SOAP web-service responses, exports from ERP and accounting systems, government open-data releases, product feeds for marketplaces, Office and LibreOffice files under the hood, OFX 2 bank statements, configuration files such as Maven's pom.xml. The shape is always the same: one root element and, somewhere inside it, an element that repeats once per record, with the values in child elements, in attributes, or both.
That repeating element is what a table needs, and finding it is the only real decision in the conversion. The converter counts how often each element name occurs under one parent, prefers elements that have children or attributes over plain values, and among those the one closest to the root: in an RSS feed that is item rather than category, in a catalog product rather than tag. The select shows every element that repeats and how many rows it would give, plus the root for a one-row table.
How elements and attributes become columns
Every value in a row gets a column named by its path from the row element. Take one product from a catalog with attributes, a nested dimensions element and two tag elements:
- Attributes are marked with @ so a column never collides with a child element of the same name; turn "Attributes as columns" off to leave them out entirely.
- A child element that repeats anywhere in the document is indexed in every row, so the header reads tag[0] for a product with one tag as well; the record with the most repeats sets the number of columns.
- Columns are the union of what all rows contain, in the order they first appear. A row missing an element gets an empty cell; an empty element such as <note/> gives an empty cell too.
- Values are taken exactly as written: 007 stays 007, 1e3 stays 1e3, true stays the word true. CSV has no types, so nothing is converted.
| Column | Value | Comes from |
|---|---|---|
| @id | p-101 | an attribute of the row element |
| name | Desk lamp | a child element with text |
| price | 39.90 | the text of an element that also has attributes |
| price.@currency | USD | an attribute of that child element |
| dimensions.width | 18 | an element nested one level deeper |
| tag[0], tag[1] | home, lighting | a child element that repeats inside the row |
What CSV cannot carry
CSV is a grid of text. Everything that XML can express beyond that is flattened or dropped, and it is worth knowing which is which. Nesting becomes dot paths in the header, attributes keep the @ marker, and that is the whole record of the document's structure. Comments, processing instructions and the XML declaration are dropped. Entities are decoded, so & comes out as &, and CDATA sections become plain text. Whitespace around values is trimmed.
Mixed content, text interleaved with child elements as in <p>Hello <b>world</b>!</p>, does not survive: the text pieces are joined into one cell and their position relative to the child elements is lost. Namespace prefixes stay part of the names (dc:creator), but namespace declarations are treated as ordinary attributes. Element order within a record becomes column order, which is fine for data files and meaningless for documents.
Opening the CSV in Excel, Google Sheets and Numbers
- The file is UTF-8 without a byte order mark, with CRLF line endings as RFC 4180 describes and with double quotes around any field that contains the delimiter, a quote or a line break (inner quotes doubled). Most tools read that as is.
- Excel on Windows assumes the system code page when you double-click a CSV, so ä, é or 中 can come out garbled. Use Data › From Text/CSV, choose 65001: Unicode (UTF-8), and while you are there set columns like SKU or ZIP to Text so 00123 keeps its zeros and 1e3 is not turned into 1000.
- In countries where the comma is the decimal separator (Germany, France, Spain, Italy and others) Excel expects a semicolon between fields; choose Semicolon here or the whole row lands in one cell.
- Google Sheets (File › Import) detects the delimiter and reads UTF-8; Numbers and LibreOffice Calc open the file directly and ask about the delimiter.
- Tab-separated output pastes straight into an open sheet: copy the text, click a cell, paste.
Questions and answers
Does the XML keep attributes?
Yes. Attributes of the row element become columns named @id, @type and so on; attributes deeper down are named by their path, such as price.@currency. The text of an element that also has attributes appears under the element's own name. Switch "Attributes as columns" off to drop them.
The converter picked the wrong element as a row. What do I do?
Open "Row element": it lists every element that repeats in the document, with the number of rows each would give, and the root element for a single row. Choosing a deeper element, for example the line items inside orders, gives one row per line item; the enclosing order's fields are not repeated on each line.
My XML has only one record. Why is the table one row?
Nothing repeats, so the whole document is taken as one row and its elements become the columns, with paths such as customer.name. That is the right result for a single record; paste a file with several records to get a table with one row each.
Why does Excel put everything in one column?
Your Excel is set to a locale that uses the semicolon as the list separator. Convert again with the Semicolon delimiter, or import the comma version through Data › From Text/CSV and set the delimiter there.
Can it handle a very large XML dump?
The conversion runs in your browser's memory, so files of tens of megabytes are fine if you drop the file rather than paste it. A multi-gigabyte dump (a Wikipedia or Stack Exchange export) needs a streaming tool on your computer, such as xmlstarlet or a short script with a SAX or iterparse reader.