XML to TSV
Flatten an XML document into a table. The hard part of this conversion is deciding what a "row" is, so the tool guesses: it finds the element that repeats most often as a sibling — <item>, <record>, <row>, <product> — and treats each occurrence as a row, with the union of its child tags as the columns. If the guess is wrong, name the element yourself. The reverse is TSV → XML.
How to use
- Paste or drop the XML. The status line reports which element it picked as the row and how many it found — check that number against what you expected.
- Override the guess if needed. Type the tag name in row element — no angle brackets, just
entry. - Decide about attributes. With the box ticked,
<item id="7">contributes an@idcolumn, and a child's attributes appear aschild@name. - Copy or download. Columns come out in first-seen order, so the first record's field order sets the layout.
How nesting is flattened
One level of nesting maps cleanly: each direct child element of a record becomes a column, and its text content becomes the cell. Deeper nesting is collapsed — a child that itself contains elements contributes its whole concatenated text, which is rarely useful. When a record has the same child tag more than once (a list of <tag> elements, say), the values are joined with ; into a single cell rather than spilling into extra columns, so the grid stays rectangular.
If your XML is deeply nested — a SOAP envelope, an XHTML fragment, a config tree — a flat table is the wrong target and you'll get poor results whatever the tool. Convert to JSON with a dedicated parser first and reshape from there; jsontoolskit.org handles that side. This page is aimed at the common flat-record case: API exports, RSS, database dumps, sitemaps, spreadsheet-ish XML.
Namespaces and entities
Namespaced tags keep their prefix, so <dc:creator> becomes a column named dc:creator and you'd type that exact string to select it as the row element. Standard entities (&, <, é) are decoded by the browser's XML parser before the text reaches the table. Malformed XML fails loudly with the parser's own message and a character position rather than producing a half-converted file — XML is strict by design, and quietly guessing at broken markup would be worse than the error.
FAQ
It picked the wrong element as the row.
This happens when a nested tag repeats more often than the actual record — a document with 50 records each containing three <tag> children may pick tag. Type the record's tag name into row element and the count in the status line should drop to the number of records you expect.
Can it convert an RSS or Atom feed?
Yes, and it's a good fit: auto-detection usually lands on item for RSS or entry for Atom, giving you a row per post with title, link, and date columns. Nested <author><name> structures collapse to their text, so you may want to name the element explicitly for those.
Why are some cells empty?
Because the columns are the union of every record's fields. A record that omits an optional tag gets an empty cell for it — that's the correct flattening, not a parse failure. Stats will show you how many nulls each column has.
What about very large XML files?
The whole document is parsed into a DOM in memory, which costs several times the file size in RAM. Up to tens of megabytes is fine on a desktop; beyond that a streaming parser (xmlstarlet, Python's iterparse) is the right tool.
Privacy
100% client-side. Parsed by your own browser's XML parser. See the privacy policy.