Skip to content
LocalOnly
Converters

How to Convert JSON to XML in JavaScript and Python

A library escapes the text for you, but it will happily write XML that is not valid. Here is tested JSON to XML code for Node and Python, and the three inputs that break it.

Updated October 18, 20263 min readTool runs in your browser

To convert JSON to XML in code, use a library and then check the result. The JSON to XML Converter converts a document in the browser, and its page explains why the two data models do not line up exactly. When a system that speaks XML has to receive your JSON data, the conversion moves into code.

This guide shows it in Node with fast-xml-parser and in Python with the standard library, then the inputs that produce invalid XML. Every output below comes from running the code.

Convert JSON to XML in Node.js

import { XMLBuilder } from "fast-xml-parser";

const order = {
  order: {
    "@_id": "ord_1",
    customer: "O'Brien & Co",
    items: { item: [{ sku: "A-1", qty: 2 }, { sku: "B-7", qty: 1 }] },
    note: "<fragile>",
  },
};

new XMLBuilder({ ignoreAttributes: false, format: true }).build(order);
<order id="ord_1">
  <customer>O&apos;Brien &amp; Co</customer>
  <items>
    <item>
      <sku>A-1</sku>
      <qty>2</qty>
    </item>
    <item>
      <sku>B-7</sku>
      <qty>1</qty>
    </item>
  </items>
  <note>&lt;fragile&gt;</note>
</order>
  • Keys starting with @_ become attributes when ignoreAttributes is false. Without that option, the builder leaves them out.
  • An array becomes one element per item, all with the key's name, so item: [...] produces two <item> elements. Wrapping them in items is your choice of shape, not something XML requires.
  • &, < and > in text are escaped automatically, so text from users cannot break the document.

Convert JSON to XML in Python

import xml.etree.ElementTree as ET

def to_element(tag, value):
    element = ET.Element(tag)
    if isinstance(value, dict):
        for key, child in value.items():
            children = child if isinstance(child, list) else [child]
            for item in children:
                element.append(to_element(key, item))
    else:
        element.text = "" if value is None else str(value)
    return element

order = {"customer": "O'Brien & Co", "item": [{"sku": "A-1"}, {"sku": "B-7"}], "note": "<fragile>"}
ET.tostring(to_element("order", order), encoding="unicode")
# <order><customer>O'Brien &amp; Co</customer><item><sku>A-1</sku></item><item><sku>B-7</sku></item><note>&lt;fragile&gt;</note></order>

ElementTree escapes & and < itself. Note str(value): Python writes booleans as True and False. If the receiving system expects true and false, convert booleans explicitly.

Three inputs that produce invalid XML

Neither library checks that the result is valid XML. These three cases need handling before conversion:

  • More than one root. An XML document has exactly one root element. { tags: ["a", "b"] } builds <tags>a</tags><tags>b</tags>, two roots. Wrap the data in a single top-level key first.
  • Keys that are not valid element names. JSON keys can be any string; XML names cannot contain spaces or start with a digit. The builder turned { "first name": "Ada", "2fa": true } into <first name>Ada</first name><2fa>true</2fa>, which no XML parser accepts. Rename such keys, for example to first_name and two_factor, or store the original key as an attribute.
  • null. JSON has a null; XML does not. Decide on a convention, such as an empty element or leaving the element out, and use it consistently. Python's function above writes an empty element.

When the receiving side publishes an XML Schema (XSD), validate the generated XML against it in a test. That catches naming, ordering and required-element problems before the first real request.

Frequently asked questions

Command Palette

Search for a tool or command