xmltoolskit.org
XML utilities, in the browser
Say hi →

CSV to XML

updated 20 August 2026 · delimiter auto-detect · elements or attributes

Paste a spreadsheet export and get XML back. Each row becomes one element, each column a child element or an attribute, and the delimiter is detected for you — comma, semicolon, tab, or pipe.

csv → xml
Drop a .csv file here, or
ready

CSV to XML

The header row supplies element (or attribute) names; every following row becomes one <row> element under a single root. Quoted fields, embedded commas and newlines, doubled quotes, CRLF endings and a UTF-8 BOM are all handled, and names that XML would reject are sanitised so the output always parses.

How to use it

  1. Paste your CSV into the left pane, or drop a .csv file on it.
  2. Name the root and row elements — rows/row by default, or something your consumer expects such as catalog/product.
  3. Choose whether each column becomes a child element or an attribute on the row.
  4. Check the result, then Download .xml.

Elements or attributes?

Child elements are the safer default: any value can later grow children of its own, long text is comfortable, and most XSDs are written that way. Attributes are far more compact — one line per row instead of one line per field — and read well when every value is a short scalar.

The one thing attributes cannot do is nest. If a column might later hold structured data, keep it as an element.

Names that XML will accept

XML element names cannot contain spaces or most punctuation and cannot start with a digit. Header cells are sanitised on the way through: disallowed characters become hyphens and a leading digit gets an underscore prefix. Duplicate headers get a numeric suffix so no column is silently dropped, and an empty header cell becomes col3 for the third column.

If your headers are human labels — "Max Retries", "Unit Price" — set Names to snake_case and they become max_retries and unit_price instead of hyphenated approximations.

Everything stays text

XML has no types, so numbers and booleans come out as text nodes and it is the reader (or your XSD) that decides what they mean. Nothing is coerced or reformatted here — a value with leading zeros keeps them, which is what you want for zip codes and account numbers.

FAQ

How are quoted fields with commas handled?

Correctly, per RFC 4180: a field wrapped in double quotes may contain the delimiter and newlines, and a doubled quote inside it means a literal quote. A UTF-8 BOM is stripped and CRLF endings are handled.

Can I skip empty cells?

Yes — tick skip empty cells and a blank value produces no element (or no attribute) at all, rather than an empty one. Leave it off if the consumer expects every row to have the same shape.

What if my CSV has no header row?

Set Header row to no header and columns are named col1, col2, and so on, with every line treated as data.

Is the delimiter really detected automatically?

The first line is scanned for commas, semicolons, tabs and pipes and the most frequent one wins. Set it explicitly for a single-column file, or when a quoted field contains more separators than the real delimiter.

Does it validate the result?

The generator escapes text and sanitises names, so the output is well-formed by construction. Run it through the validator if you want the confirmation, or the schema validator to check it against an XSD.

Related tools

Privacy

100% client-side. Your spreadsheet is parsed in the page and never uploaded. See the privacy policy.