← All XML tools
XML Tools

XML ↔ CSV Converter

Convert XML to CSV or CSV to XML, either direction. Detects repeating elements to use as rows, keeps attributes distinct from child elements, and never silently drops data it can't flatten cleanly.

Use the tool ↓
XML input drop a file here 0 chars
CSV output 0 chars
Paste XML with repeating elements to convert it to CSV.

About this tool

CSV is a flat, row-and-column format; XML is a tree. Converting between them only really works cleanly when the XML represents a list of similar records — the classic case being something like <customers> containing many <customer> elements that each look roughly the same. This tool is built around that case in both directions.

XML → CSV

The converter scans your document for a repeating element — siblings that share the same tag name under the same parent — and uses that as the row. If more than one repeating structure exists in your document, a dropdown lets you pick which one to use as rows. For each row, its attributes become columns prefixed with @ (so an id attribute becomes an @id column), and its child elements become ordinary columns. A child element that's itself nested one level deeper (like an <address> containing <city>) is flattened into a dot-notation column such as address.city.

Not everything flattens cleanly. If a row contains a child element that itself repeats — say a product with several <category> tags — there's no single CSV cell that can represent a list. Rather than silently keeping only the first value, this tool joins the repeated values into one cell with a | separator and calls this out explicitly in the warnings under the result, so you know that column needs a closer look rather than assuming it's complete.

CSV → XML

Each data row becomes one instance of your chosen row element, nested inside your chosen root element. A column header starting with @ (matching the convention this tool itself uses going the other direction) becomes an attribute on the row element instead of a child element — so a round trip through XML → CSV → XML preserves the attribute/element distinction rather than flattening everything into child elements. Column names that aren't valid XML tag names (spaces, a leading digit, stray punctuation) are automatically sanitized, and you'll see a warning if that causes two different columns to collide on the same name.

Delimiters and quoting

Both directions support comma, tab, semicolon, or a custom single/multi-character delimiter. Parsing follows the standard CSV quoting convention: a field containing the delimiter, a double quote, or a line break is wrapped in double quotes, and a literal double quote inside a quoted field is written as two double quotes in a row (""). This tool's own CSV parser and writer both follow this convention, so output from one direction reads back correctly in the other. Everything runs locally in your browser; nothing you paste or upload is sent to a server.

How to use it

  1. 01

    Pick a direction

    XML → CSV to flatten a document into rows, or CSV → XML to build a document from tabular data.

  2. 02

    Set your options

    Choose the delimiter; for XML → CSV, confirm which repeating element to use as rows if more than one is found; for CSV → XML, set the root/row element names, header-row toggle, and indent.

  3. 03

    Paste, upload, or drop your file

    The output updates live. Check the status bar and any warnings underneath — they call out anything that couldn't be represented without a judgment call.

  4. 04

    Copy or download the result

    Copy to your clipboard or download as a standalone .csv or .xml file.

Example

XML
<customers>
  <customer>
    <name>John</name>
    <city>Delhi</city>
  </customer>
  <customer>
    <name>Amy</name>
    <city>Cork</city>
  </customer>
</customers>
CSV
name,city
John,Delhi
Amy,Cork

Common use cases

Opening XML exports in a spreadsheet

Turn an XML export from another system into CSV so it opens cleanly in Excel or Sheets.

Bulk-importing tabular data as XML

Convert a CSV of records into the XML shape an import tool or legacy system expects.

Auditing a record set

Flatten XML records to CSV to sort, filter, and eyeball data quality in a spreadsheet.

Preparing test fixtures

Generate sample XML records quickly from a CSV you already have, for testing a parser or API.

Migrating between systems

Move record data from an XML-based system to a CSV-based one, or vice versa.

Reporting

Extract a flat, reportable table from a deeper XML document for a one-off analysis.

Limitations

  • XML → CSV needs at least one repeating element to use as a row; a document with no repeated sibling tags (a single settings/config-style document, for instance) has no natural "rows" and can't be converted.
  • Only one level of nested elements is flattened automatically into dot-notation columns. Deeper nesting beyond that is included as a dot path when possible, but very deep or irregular structures are better handled with the XML ↔ JSON tool instead.
  • A child element that repeats inside a single row (a list-within-a-row) can't become a normal CSV column; it's joined into one cell with |, and this is always flagged in the warnings so it isn't mistaken for a complete, structured value.
  • CSV → XML produces flat child elements from column names, including dot-notation names — it does not reconstruct multi-level nesting from a dotted header like address.city; that becomes a literal element named address.city, not a nested <address><city>.
  • Very large files will take longer, since the browser parses and rebuilds the whole structure in memory.

Troubleshooting

  • "No repeating element found" — your XML doesn't have multiple sibling elements sharing a tag name anywhere. CSV conversion needs a list of similar records to work from.
  • Unexpected columns joined with | — that column corresponds to a child element that repeats inside a single row. Check the warnings list; it names exactly which column this happened to.
  • "Unterminated quoted field" — a " was opened in your CSV but never closed. Check for a stray quote character, or a quoted field that's missing its closing quote before the next comma or line break.
  • Columns shifted after a certain row — that row likely has more or fewer fields than the header. This tool pads short rows with empty values and flags the mismatch rather than silently misaligning your data.
  • An element name looks different than the column header you typed — column headers are sanitized into valid XML tag names (spaces become underscores, leading numbers are stripped, etc.). Two headers that sanitize to the same name will have the second one renamed, and this is called out in the warnings.

Frequently asked questions

How does the tool decide which element to use as a row?

It looks for the repeating element with the highest sibling count in your document. If your XML has more than one repeating structure, all candidates appear in the "Row element" dropdown so you can pick the right one.

What happens to XML attributes?

Going to CSV, each attribute on the row element becomes its own column named @attributeName. Going back to XML, a column header starting with @ is converted back into an attribute on the row element rather than a child element.

Can I use a delimiter other than comma?

Yes — tab and semicolon are built in, and you can also type any custom delimiter (including multi-character ones).

What if my CSV doesn't have a header row?

Turn off "First row is header." Every row is then treated as data, and columns are named column1, column2, and so on.

Does it handle quoted fields with embedded commas or line breaks?

Yes, following the standard CSV convention: a field containing the delimiter, a quote character, or a line break is wrapped in double quotes, and an embedded quote is written as two double quotes in a row.

Why did some of my data get joined with a "|" character?

That happens when a child element repeats inside a single row — for example a product with three <category> tags. CSV cells can't hold a nested list, so the values are joined rather than dropped, and the warnings list always names which column this affected.

Will nested XML always convert cleanly?

One level of nesting flattens automatically into dot-notation columns (like address.city). Deeper or more irregular nesting is better suited to the XML ↔ JSON tool, which preserves full structure rather than flattening it.

What happens with duplicate column headers in my CSV?

The second and any later occurrence gets a numeric suffix (like name_1) so every element or attribute in the output XML has a unique name, and this is flagged in the warnings.

Does this tool upload my file anywhere?

No. Parsing and conversion both happen locally in your browser, including files you upload or drag in. Nothing is sent to a server.

Is there a file size limit?

No hard limit is enforced, but very large files take longer since your browser has to hold and process the entire structure in memory.

Related tools