creatorvalet Search

Convert CSV to XML

Your header row names the elements. Headers XML will not accept are rewritten by a rule you can read, on screen, before you download.

  • SECURE
  • NO UPLOADS
  • NO SIGNUP
  • BROWSER BASED
  • FREE
  • FOREVER.

Support us with a link or a share

Waiting
Rows
Columns
Separator
Encoding
already text
№ 2608waiting

Paste rows or drop a .csv file — the element names appear before anything is converted.

Values as

<rows><row>…</row></rows> — names follow the same rule as the headers.

Indent
Empty cell

A CSV column can be called anything. An XML element cannot.

Every other part of this conversion is mechanical. A row becomes an element, a cell becomes the text inside a child element, and the file is done. The one place a converter can be good or bad is the header row, because that is where two formats disagree about what a name is allowed to be.

A spreadsheet column can be called First Name, 2026 sales, Unit price ($) or nothing at all. An XML element name follows a grammar: no spaces, no parentheses, no currency signs, and it may not begin with a digit, a hyphen or a full stop. Hand <First Name> to any parser and it stops on the first row. So a header that XML will not accept has to be rewritten — the only question is whether you get told how.

The rewriting rule, in full

Five steps, applied in this order, and every one of them is visible in the element list under the tool before you download anything:

  1. Whitespace around the header is trimmed.
  2. Every character XML does not allow inside a name becomes one underscore — one per character rather than one per run, so a b gives a__b and you can still tell how many characters were replaced.
  3. If the name still starts with something a name cannot start with — a digit, a hyphen, a full stop — it gains a leading underscore. 2026 sales becomes _2026_sales.
  4. Names beginning with the letters xml, in any mix of case, are reserved by the specification, so those gain a leading underscore too.
  5. A column with no header at all is named after its position: column_3. It is never dropped, and no row of your data is ever consumed to invent a name for it.

A colon is the interesting case. It is technically legal inside an XML name, which is why some converters leave it alone, but XML Namespaces reserves it to mean “everything before this is a declared prefix”. A header called order:id means a column with a colon in its name; it does not mean a namespace called order, and a namespace-aware parser will reject the document for referring to a prefix nothing declared. So the colon is rewritten here, and the reason is written on the line next to it.

Why your ampersand comes back doubled, and why that is correct

Three characters are markup in XML: &, < and >. Inside an attribute a double quote joins them. Each one is written as an entity, which is ordinary and uninteresting until a cell already contains something like AT&amp;T.

That cell holds five characters: an ampersand, then a, m, p and a semicolon. Write them raw and an XML parser resolves the entity and hands the recipient a single ampersand — five characters in, one character out, silently. Escaping the ampersand again produces &amp;amp;, which a parser turns back into exactly the five characters your file held. It looks like a bug in a preview. It is the difference between a converter that preserves your data and one that quietly rewrites it, and it is the reason this page reports how many cells in each column were escaped and shows one of them before and after.

Two smaller cases follow the same logic. A carriage return is written as &#13;, because an XML parser normalizes a literal carriage return to a line feed before your program ever sees it. And in attribute mode line breaks and tabs are written as numeric references as well, because attribute values are normalized harder still — every literal one of them arrives as a plain space.

Child elements or attributes, and the rule that actually differs

Child elements are the default. They read better, they hold line breaks without a fight, and most things that consume XML expect them. Attributes make a much smaller file and are what some older importers want.

There is one real difference beyond taste. XML allows two sibling elements to share a name — <row><id>1</id><id>2</id></row> is perfectly well-formed and means what it looks like. It forbids two attributes on one element sharing a name, and that is a fatal error rather than a matter of style. So a file with two columns called id converts cleanly as elements and needs one of them renamed as attributes. This tool renames it only in the mode that requires it, and tells you which column it renamed. That is the opposite of what happens on the CSV to JSON converter, where an object cannot hold a duplicate key at all and the second one always has to be numbered.

Characters XML cannot carry at any price

Most of the ASCII control characters are excluded by XML 1.0 outright. Not “discouraged” — there is no valid XML document containing a U+0007, and you cannot smuggle one in as &#7; either, because the numeric reference is exactly as invalid as the character. They turn up in real exports more often than you would think, usually from a database field that once held a terminal escape sequence.

Nothing here refuses a file over that, or over its size. The characters that cannot exist in the format are removed, the rest of the cell is kept exactly as it stands, and the column, the count and the code point of the first one are printed. A limit that comes from the format is worth stating; a limit invented by the converter is not.

What this does not do, and what to use instead

There is no template mode with ##1## placeholders. FreeFormatter needed one because it did not read your header row at all — the template was how you told it what the columns were called. Here the header row does that job, so a template would be a second way to say the same thing, and a setting that duplicates a default is a setting nobody can predict.

There is also no XML to CSV converter here, and that is a judgement rather than an oversight. This direction is always honest: every grid can be written as a list of elements. The return trip is not, because a CSV is a grid and an XML document is a tree, and an arbitrary tree — nested three deep, with repeated children and attributes on the branches — has no obvious grid form. A converter that pretends otherwise picks one for you. If what you have is an XML document you need to read rather than reshape, the XML formatter indents it and shows you its structure. And when the XML that comes out of here has to become a different shape of XML — or HTML, or plain text — that is what a stylesheet is for: the XSLT transformer runs one against it in the same tab, with nothing uploaded either.

Many people arrive at this problem from Excel, which can indeed export XML — but only after you attach an XML Map to the workbook, which means writing a schema first. That is the right route when the receiving system dictates a schema. It is a great deal of work when what you actually wanted was your rows in angle brackets. If the source is a workbook rather than a .csv, CSV to Excel goes the other way for the same family of files. Why a separator picker and an encoding picker are needed under the tool at all is its own story, told in this explanation of the CSV format: there is no standard to appeal to, only conventions that disagree.

Where the CSV to XML conversion actually runs

Inside this tab, start to finish. Decoding the bytes, naming the elements and assembling the document happen in JavaScript that arrived with the page, and nothing on this domain will take a spreadsheet even if you aim one at it. Past roughly half a megabyte the job moves onto a background thread and the document is assembled in slices, which is why the bar you see counts rows already written rather than time already spent — a bar that filled at a steady pace regardless of the file would be decoration pretending to be information. Two of the four converters ranking above this page for the same search post your rows to a server, and one of them says as much in its opening sentence. Given that a spreadsheet headed for XML is typically an order feed, a product catalog or a staff list, that difference is worth more than any feature comparison, and your network panel will settle it in about four seconds.

Separator detection, quoting and encoding are shared with the rest of the CSV family here, so a semicolon file from a European Excel and a UTF-16 export from a database both read the same way they do on the CSV viewer and on CSV to SQL. What is different on this page is only what comes out the other end.

Have an idea for this tool?

Tell us what would make this tool more useful, or suggest another tool you would like us to build.

Questions

What happens to a column called "First Name"?

It becomes <First_Name>, and the page tells you so before you download anything. An XML element name cannot contain a space — that is the format’s rule, not a preference — so every character XML will not accept becomes exactly one underscore. One per character rather than one per run, so that "a b" gives a__b and you can still tell how many characters were replaced. A header that starts with a digit gets a leading underscore, because a name cannot start with one either, and a column with no header at all is named after its position: column_3.

Why does my cell that said &amp; come out as &amp;amp;?

Because that is the only answer that gives your data back unchanged. If the cell literally holds the five characters & a m p ;, then writing them raw means an XML parser hands the recipient a single & — five characters in, one character out. Escaping the ampersand again produces &amp;amp;, which a parser turns back into exactly the five characters that were in your file. It looks wrong in a preview and it is the difference between a converter that preserves your data and one that quietly rewrites it.

Should the values be child elements or attributes?

Child elements unless something at the other end wants attributes. They read better, they hold line breaks without a fight, and — the real difference — XML allows two sibling elements with the same name but forbids two attributes with the same name on one element. So a file with two columns called "id" converts cleanly to elements and needs one of them renamed to id_2 as attributes. This tool does that rename only in attribute mode, and says which column it renamed.

Is there an XML template mode with placeholders?

No, and that is deliberate. FreeFormatter required you to write a template with ##1## placeholders because it did not read your header row at all — the template was how you told it what the columns were called. Here the header row is the default and does that job, so a template would be a second way to say the same thing. If a real case turns up that the header row cannot express, it gets built then.

Does my file get uploaded anywhere?

It does not. Naming the elements and writing the document are ordinary function calls executing inside this tab, using the file-reading API every browser has built in; nothing on this domain will accept a file even if you point it at one. Watch your network panel while you drop a spreadsheet and you will see it stay quiet. Two of the four converters ranking above this page for the same search send your rows somewhere first, and one of them announces it in its opening line. Since a spreadsheet on its way into XML is generally an order feed, a product catalog or a staff list, that distinction is the only one worth caring about.