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

XML to SQL

updated 20 August 2026 · INSERT statements · optional CREATE TABLE

Turn an XML dataset into SQL you can paste into a client: one multi-row INSERT, or one statement per record, with identifiers quoted for your dialect and every value escaped.

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

XML to SQL

The repeating record element becomes the table, its child elements become the columns, and each record becomes a row. Identifiers are sanitised and quoted ("col" for ANSI and Postgres, `col` for MySQL), string literals have their single quotes doubled, and empty values become NULL or '' as you choose.

How to use it

  1. Paste your XML, or drop a file on the left pane.
  2. Name the target table — leave it blank to use the record element's name.
  3. Pick your dialect so identifier quoting is right, and decide between one multi-row INSERT and one statement per record.
  4. Tick CREATE TABLE if you also need the DDL, then copy or download the .sql.

Multi-row or one per record

A single multi-row INSERT … VALUES (…),(…),(…) is much faster to execute and easier to wrap in a transaction, and it is what you want for a bulk load. One statement per record is more verbose but far easier to edit by hand, and a single bad row does not take the whole batch down.

Very large datasets should be split into batches of a few thousand rows regardless of the style you pick — most clients and servers have statement-size limits.

Values, types, and NULL

With unquote numbers on, values that look like integers or decimals are emitted bare, and true/false become the dialect's boolean form (1/0 on MySQL). Everything else is a quoted string with internal quotes doubled. Turn it off when a column of digits is really text — a zip code, a leading-zero identifier, a phone number.

An element that is present but empty becomes NULL by default, which is usually the honest reading of <price/>. Switch to empty string if your column is NOT NULL.

The generated DDL is a starting point

The optional CREATE TABLE declares every column as TEXT. That is deliberate: guessing INT from one sample is how migrations get truncated data. Edit the DDL to real types before you run it in anything but a scratch database.

FAQ

Which element becomes the table?

The one that repeats most often, or whatever you type into Record element. Its name is also the default table name, which you can override in the Table box.

How are nested elements handled?

One level of nesting is flattened into a dotted name, which is then sanitised into a legal column identifier — price.amount becomes price_amount. Deeper structures need a real relational design rather than a flattening.

Is SQL injection a concern?

The output is a script you review and run yourself, not a query built at runtime. Single quotes in values are doubled so the literals are well-formed, but always read generated SQL before executing it against anything that matters.

Does it handle attributes?

Yes, with include attributes on: an attribute becomes a column named after it, and namespace declarations are skipped.

Can I load the result straight into MySQL?

Pick the MySQL dialect so identifiers use backticks and booleans become 1/0. Then check the DDL types — the generated columns are all TEXT by design.

Related tools

Privacy

100% client-side. The XML never leaves your browser, which matters for production data extracts. See the privacy policy.