Convert CSV to XML

Drop a CSV here

or paste it below — .csv, .tsv, .txt

Conversion options

Paste a CSV or drop a file in and get well-formed XML back, with each row as an element and each column as a child element or an attribute. CSV headers can be anything - spaces, punctuation, a leading digit - and XML tag names cannot, so a converter has to rename some of them. This one lists every rename and keeps apart any two columns that would have ended up with the same name, which in attribute mode would otherwise produce a file no parser can open. Nothing is uploaded.

How to convert CSV to XML

  1. Drop a .csv file into the box above or paste the rows into the CSV field. Nothing is uploaded either way.
  2. Leave the delimiter on Detect automatically unless the guess is wrong — comma, semicolon, tab and pipe are all recognised.
  3. Name the root element and the element that wraps each row, and choose whether columns become child elements or attributes.
  4. Press Convert to XML and read the report before you copy the result. Renamed and separated columns are the part worth looking at.

CSV headers are not XML names

A CSV header can say anything: order id, 2024 total, price ($). An XML element name cannot. It must start with a letter or an underscore, it cannot contain spaces or most punctuation, and it may not begin with the letters xml in any casing. So every CSV to XML converter has to rename some of your columns, and a file exported from a spreadsheet nearly always needs it.

Column headerWhy it is illegalBecomes
order idSpaceorder_id
2024 totalStarts with a digit_2024_total
price ($)Punctuationprice____
xmlnsReserved prefix_xmlns

The renaming itself is unavoidable. Doing it without saying so is not: the converter we looked at most closely documents no rule for illegal names at all, so you find out what your columns became by reading the output. Here every change is listed.

When two columns become one tag

Suppose a spreadsheet has both user name and user_name — two columns, which happens whenever data from two systems is pasted side by side. Both clean up to user_name. Written as child elements, the file is valid but the two values sit under the same tag and nothing says which came from where.

Written as attributes it is worse: <row user_name="Ada" user_name="ada99"/> is not well-formed XML at all, and no parser will open it. This tool numbers the later column (user_name_2) in both modes, so the file always parses and the two values stay apart, and it names the pair in the report so you know it happened.

Elements or attributes?

Child elementsAttributes
Looks like<row><name>Ada</name></row><row name="Ada"/>
File sizeLarger — every value carries a closing tagSmaller, often by a third or more
Line breaks in a valueKept as they areWritten as &#10; so they survive
Best whenAn importer or schema expects elements, or values are longRows are flat and short, like a lookup table

Whichever you pick, follow the schema of whatever will read the file. There is no universally right answer — only the one your importer wants.

What is left as it was

XML has no number type, so nothing here is converted. A postcode like 00721 stays 00721, a 19-digit account number keeps every digit, and 1e5 is still the text 1e5. Any typing happens later, in an XML Schema. Characters that XML treats specially — &, <, > and, inside attributes, quotes — are escaped, so the file reads back as what you put in. The few control characters XML 1.0 cannot carry at all are removed and counted.

Next steps

XML to CSV goes back the other way and lists the candidate record elements with their counts. CSV to JSON and JSON to XML cover the other routes, and every converter is listed on the data tools page.

Frequently asked questions

What happens to a CSV header that is not a legal XML name?

It is renamed, because XML element names cannot start with a digit, cannot contain spaces or most punctuation, and cannot begin with the letters xml in any casing. Illegal characters become underscores and a leading digit gets an underscore in front of it. Every rename is listed on the page, so the mapping between your spreadsheet columns and the tags in the file is written down instead of happening silently.

Two of my columns ended up with the same name. What did you do?

The later one was numbered. Columns called user name and user_name are different in the CSV but both clean up to user_name, and the second becomes user_name_2. That matters most in attribute mode, where two identical attribute names make the file invalid XML and no parser will open it. The page names each pair it separated.

Should I choose elements or attributes?

Whichever the reader of the file expects. Child elements are the common default and keep line breaks inside values as they are. Attributes make a flat table noticeably smaller, and any line break in a value is written as a character reference so it survives. If you are feeding an importer or a schema, follow its documentation - there is no universally correct choice.

Will my postcodes and long IDs survive?

Yes. XML has no number type, so nothing is converted: 00721 stays 00721, a 19-digit account number keeps every digit, and 1e5 stays the text 1e5. Typing values as numbers or dates is done later by whatever reads the XML, usually through an XML Schema.

What if a row has more or fewer cells than the header?

It is still converted and it is counted. A short row gets empty values for the missing columns instead of shifting the rest along. A long row keeps its surplus cells as column_N elements, numbered by position, so nothing is dropped. The report says how many rows were short and how many were long.

What does the file do about line breaks inside a quoted CSV field?

It reads them correctly. A postal address with a line break inside quotes is one record, not two, because the parser tracks quotes character by character instead of splitting on newlines first. The report shows the text-line count beside the record count, and when they differ you are looking at a file a line-based tool would have cut in half.

Can I leave out empty cells?

Yes, with the option to leave them out. By default an empty cell becomes an empty element or attribute, which keeps every row the same shape. Leaving them out gives smaller files, but the reader can then no longer tell a missing value from an empty one, and the report says how many cells were affected.

Is my data uploaded?

No. The file is read and converted inside your browser tab, so customer lists and exports never travel to a server. There is no size limit imposed by an upload, only by your own device's memory.