Why Convert JSON to XML?
Common reasons to convert JSON to XML:
- SOAP API Integration - Enterprise web services use XML/SOAP
- Legacy Systems - Many older systems only accept XML
- Configuration Files - Some apps require XML config (Android, Maven)
- Data Exchange - EDI, healthcare (HL7), and financial systems use XML
- RSS/Atom Feeds - Syndication formats are XML-based
- Document Formats - Office documents, SVG, and MathML are XML
When to Use XML Over JSON:
| Use Case | XML Advantage |
|---|---|
| Document markup | Mixed content support |
| Namespaces needed | XML namespace support |
| Schema validation | XSD provides strict validation |
| XSLT transformation | Built-in transformation language |
| Comments required | JSON doesn't support comments |
Convert JSON to XML in JavaScript
Build XML from JSON using string templates or DOM:
// Method 1: String-based conversion
function jsonToXml(obj, rootName = 'root', indent = 0) {
const spaces = ' '.repeat(indent);
if (obj === null || obj === undefined) {
return `${spaces}<${rootName}/>`;
}
if (typeof obj !== 'object') {
const escaped = String(obj)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>');
return `${spaces}<${rootName}>${escaped}</${rootName}>`;
}
if (Array.isArray(obj)) {
const itemName = rootName.endsWith('s')
? rootName.slice(0, -1)
: 'item';
const items = obj.map(item =>
jsonToXml(item, itemName, indent + 1)
).join('\n');
return `${spaces}<${rootName}>\n${items}\n${spaces}</${rootName}>`;
}
// Object
const entries = Object.entries(obj);
const attributes = [];
const children = [];
for (const [key, value] of entries) {
if (key.startsWith('@')) {
// Attribute
const attrName = key.slice(1);
const escaped = String(value).replace(/"/g, '"');
attributes.push(`${attrName}="${escaped}"`);
} else if (key === '#text') {
// Text content
children.push(String(value));
} else {
// Child element
children.push(jsonToXml(value, key, indent + 1));
}
}
const attrStr = attributes.length ? ' ' + attributes.join(' ') : '';
if (children.length === 0) {
return `${spaces}<${rootName}${attrStr}/>`;
}
const hasOnlyText = children.length === 1 && !children[0].includes('<');
if (hasOnlyText) {
return `${spaces}<${rootName}${attrStr}>${children[0]}</${rootName}>`;
}
return `${spaces}<${rootName}${attrStr}>\n${children.join('\n')}\n${spaces}</${rootName}>`;
}
// Usage
const json = {
book: {
'@id': '1',
'@category': 'fiction',
title: 'The Great Gatsby',
author: 'F. Scott Fitzgerald',
year: 1925
}
};
const xml = '<?xml version="1.0" encoding="UTF-8"?>\n' + jsonToXml(json.book, 'book');
console.log(xml);
// Method 2: Using xmlbuilder2 (npm install xmlbuilder2)
const { create } = require('xmlbuilder2');
function jsonToXmlBuilder(obj) {
return create({ version: '1.0', encoding: 'UTF-8' })
.ele(obj)
.end({ prettyPrint: true });
}
console.log(jsonToXmlBuilder({ book: { title: 'Example', author: 'Author' } }));Convert JSON to XML in Python
Python offers multiple approaches for JSON to XML conversion:
# pip install dicttoxml
import json
import dicttoxml
from xml.dom.minidom import parseString
# Method 1: Using dicttoxml
json_data = {
"users": {
"user": [
{"name": "John", "email": "john@example.com"},
{"name": "Jane", "email": "jane@example.com"}
]
}
}
# Convert to XML bytes
xml_bytes = dicttoxml.dicttoxml(json_data, custom_root='root', attr_type=False)
# Pretty print
xml_string = parseString(xml_bytes).toprettyxml(indent=" ")
print(xml_string)
# Method 2: Using ElementTree (built-in)
import xml.etree.ElementTree as ET
def json_to_xml(data, parent=None, root_name='root'):
if parent is None:
parent = ET.Element(root_name)
if isinstance(data, dict):
for key, value in data.items():
if key.startswith('@'):
# Attribute
parent.set(key[1:], str(value))
elif key == '#text':
# Text content
parent.text = str(value)
elif isinstance(value, list):
# Array - create multiple elements
for item in value:
child = ET.SubElement(parent, key)
json_to_xml(item, child, key)
elif isinstance(value, dict):
child = ET.SubElement(parent, key)
json_to_xml(value, child, key)
else:
child = ET.SubElement(parent, key)
child.text = str(value)
elif isinstance(data, list):
for item in data:
child = ET.SubElement(parent, 'item')
json_to_xml(item, child)
else:
parent.text = str(data)
return parent
# Usage
json_data = {
"book": {
"@id": "1",
"title": "Python Guide",
"chapters": {
"chapter": ["Introduction", "Basics", "Advanced"]
}
}
}
root = json_to_xml(json_data["book"], root_name="book")
xml_str = ET.tostring(root, encoding='unicode')
# Pretty print with minidom
from xml.dom.minidom import parseString
print(parseString(xml_str).toprettyxml(indent=" "))Convert JSON to XML in PHP
PHP provides XMLWriter and SimpleXMLElement for building XML:
<?php
// Method 1: Using SimpleXMLElement
function jsonToXml($data, $rootName = 'root', $xml = null) {
if ($xml === null) {
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><' . $rootName . '/>');
}
foreach ($data as $key => $value) {
// Handle attributes (@prefixed keys)
if (strpos($key, '@') === 0) {
$xml->addAttribute(substr($key, 1), $value);
continue;
}
// Handle text content
if ($key === '#text') {
// SimpleXML doesn't support mixed content well
continue;
}
if (is_array($value)) {
// Check if it's a numeric array (list)
if (array_keys($value) === range(0, count($value) - 1)) {
foreach ($value as $item) {
if (is_array($item)) {
$child = $xml->addChild($key);
jsonToXml($item, $key, $child);
} else {
$xml->addChild($key, htmlspecialchars($item));
}
}
} else {
$child = $xml->addChild($key);
jsonToXml($value, $key, $child);
}
} else {
$xml->addChild($key, htmlspecialchars($value));
}
}
return $xml;
}
// Usage
$json = json_decode('{
"book": {
"@id": "1",
"title": "PHP Programming",
"author": "John Doe",
"price": 29.99
}
}', true);
$xml = jsonToXml($json['book'], 'book');
// Pretty print
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();
// Method 2: Using XMLWriter for more control
function jsonToXmlWriter($data, $rootName = 'root') {
$xml = new XMLWriter();
$xml->openMemory();
$xml->setIndent(true);
$xml->setIndentString(' ');
$xml->startDocument('1.0', 'UTF-8');
writeElement($xml, $rootName, $data);
$xml->endDocument();
return $xml->outputMemory();
}
function writeElement($xml, $name, $value) {
$xml->startElement($name);
if (is_array($value)) {
foreach ($value as $key => $val) {
if (strpos($key, '@') === 0) {
$xml->writeAttribute(substr($key, 1), $val);
} elseif (is_array($val) && array_keys($val) === range(0, count($val) - 1)) {
foreach ($val as $item) {
writeElement($xml, $key, $item);
}
} elseif (is_array($val)) {
writeElement($xml, $key, $val);
} else {
$xml->writeElement($key, $val);
}
}
} else {
$xml->text($value);
}
$xml->endElement();
}
?>Convert JSON to XML in Java
Java offers Jackson and org.json for JSON to XML conversion:
// Using org.json library
import org.json.JSONObject;
import org.json.XML;
public class JsonToXml {
public static void main(String[] args) {
// Simple conversion
String jsonString = """
{
"book": {
"title": "Java Programming",
"author": "John Doe",
"year": 2024
}
}
""";
JSONObject json = new JSONObject(jsonString);
String xml = XML.toString(json, "root");
System.out.println(xml);
// With pretty printing
String prettyXml = formatXml(xml);
System.out.println(prettyXml);
}
// Pretty print XML
public static String formatXml(String xml) {
try {
javax.xml.transform.Transformer transformer =
javax.xml.transform.TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(
javax.xml.transform.OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");
javax.xml.transform.stream.StreamSource source =
new javax.xml.transform.stream.StreamSource(
new java.io.StringReader(xml));
java.io.StringWriter writer = new java.io.StringWriter();
transformer.transform(source,
new javax.xml.transform.stream.StreamResult(writer));
return writer.toString();
} catch (Exception e) {
return xml;
}
}
}
// Using Jackson (more control over conversion)
// Add dependencies: jackson-databind, jackson-dataformat-xml
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class JacksonJsonToXml {
public static void main(String[] args) throws Exception {
String json = """
{"user": {"name": "John", "email": "john@example.com"}}
""";
ObjectMapper jsonMapper = new ObjectMapper();
JsonNode node = jsonMapper.readTree(json);
XmlMapper xmlMapper = new XmlMapper();
String xml = xmlMapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(node);
System.out.println(xml);
}
}Command Line Conversion
Convert JSON to XML using CLI tools:
# Using yq (brew install yq)
yq -p=json -o=xml input.json > output.xml
# Using Python with dicttoxml
python -c "
import json, sys
from dicttoxml import dicttoxml
from xml.dom.minidom import parseString
data = json.load(sys.stdin)
print(parseString(dicttoxml(data, attr_type=False)).toprettyxml())
" < input.json > output.xml
# Using Node.js with xmlbuilder2
echo '{"book":{"title":"Test"}}' | node -e "
const {create} = require('xmlbuilder2');
let data = '';
process.stdin.on('data', c => data += c);
process.stdin.on('end', () => {
const json = JSON.parse(data);
console.log(create({version:'1.0'}).ele(json).end({prettyPrint:true}));
});
"
# Using jq + custom script
jq -r 'def xml: if type == "object" then to_entries | map("<\(.key)>\(.value | xml)</\(.key)>") | join("") elif type == "array" then map(xml) | join("") else tostring end; "<root>\(xml)</root>"' input.jsonHandling JSON to XML Mapping
Special cases when converting JSON to XML:
Arrays Become Repeated Elements
{ "items": ["a", "b", "c"] }
Becomes:
1<items>2 <item>a</item>3 <item>b</item>4 <item>c</item>5</items>
@ Prefix Creates Attributes
{ "book": { "@id": "1", "title": "Example" } }
Becomes:
<book id="1"><title>Example</title></book>
#text for Mixed Content
{ "p": { "@class": "intro", "#text": "Hello World" } }
Becomes:
<p class="intro">Hello World</p>
Null Values
{ "value": null }
Becomes either empty element or self-closing:
<value></value><!-- or --><value/>
Best Practices
Follow these guidelines for JSON to XML conversion:
1. Choose Appropriate Root Element
- Use meaningful root name, not generic "root"
- Match the data domain (e.g., "order", "user", "config")
2. Handle Data Types
- JSON numbers → XML text (no native number type)
- JSON booleans → "true"/"false" strings
- Consider adding type attributes if needed
3. Escape Special Characters
Always escape these in XML:
&→&<→<>→>"→"(in attributes)
4. Validate Output
If target system has XML Schema (XSD), validate against it:
xmllint --schema schema.xsd output.xml --noout
5. Add XML Declaration
Always include XML declaration for proper encoding:
<?xml version="1.0" encoding="UTF-8"?>
6. Consider Namespaces
For SOAP or enterprise XML, you may need namespaces:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">...</soap:Envelope>