How to convert CSV to XML
- Drop a
.csvfile into the box above or paste the rows into the CSV field. Nothing is uploaded either way. - Leave the delimiter on Detect automatically unless the guess is wrong — comma, semicolon, tab and pipe are all recognised.
- Name the root element and the element that wraps each row, and choose whether columns become child elements or attributes.
- 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 header | Why it is illegal | Becomes |
|---|---|---|
order id | Space | order_id |
2024 total | Starts with a digit | _2024_total |
price ($) | Punctuation | price____ |
xmlns | Reserved 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 elements | Attributes | |
|---|---|---|
| Looks like | <row><name>Ada</name></row> | <row name="Ada"/> |
| File size | Larger — every value carries a closing tag | Smaller, often by a third or more |
| Line breaks in a value | Kept as they are | Written as so they survive |
| Best when | An importer or schema expects elements, or values are long | Rows 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.