How to Convert JSON to XML: Patterns, Examples, and Best Practices
While the industry trend is moving from XML toward JSON, there are many situations where you need to go the other direction. SOAP web services still power banking, insurance, and government systems. RSS and Atom feeds require XML. Enterprise integration buses (MuleSoft, IBM MQ, TIBCO) often expect XML messages. Configuration files for Java applications (Maven, Spring, Android manifests) are XML. If your data lives in JSON and your consumers need XML, you need a reliable conversion strategy.
This guide walks through every decision you'll face when converting JSON to XML: choosing root elements, representing arrays, mapping attributes, handling nulls, and integrating with real-world systems like SOAP services and RSS readers.
1. When You Need JSON-to-XML Conversion
JSON-to-XML conversion isn't just the reverse of XML-to-JSON. It has its own set of challenges because XML is stricter: it requires a single root element, has no native types (everything is text), and uses both elements and attributes for different purposes. Here are the most common real-world scenarios:
- SOAP API integration: Your microservice produces JSON, but the downstream partner only accepts SOAP/XML requests. You need to wrap your JSON data in an XML envelope with the correct schema.
- RSS/Atom feed generation: Your CMS stores articles as JSON objects, but feed readers expect XML. You need to transform each article into valid RSS
<item>elements. - Configuration file generation: Your deployment pipeline produces JSON configs that need to be converted to XML for Java/Spring applications, Android manifests, or IIS web.config files.
- EDI and B2B messaging: Trading partners in supply chain, logistics, and healthcare often require XML documents conforming to specific industry schemas (UBL, HL7, EDIFACT-XML).
- Report generation: Tools like Apache FOP, JasperReports, and XSLT-based transformations consume XML input to generate PDFs, HTML reports, or print layouts.
2. The Root Element Problem
Every valid XML document must have exactly one root element. JSON has no such requirement — a JSON object can have any number of top-level keys. This creates the first conversion decision: what becomes the root element?
Single top-level key (natural root)
When your JSON has exactly one top-level key, it naturally becomes the XML root element:
// JSON — single top-level key
{
"invoice": {
"id": "INV-001",
"total": 250.00
}
}
<!-- XML — "invoice" becomes root -->
<invoice>
<id>INV-001</id>
<total>250</total>
</invoice>Multiple top-level keys (wrapper needed)
When your JSON has multiple top-level keys, you must wrap them in a root element. Choose a meaningful name likedata, response, or a domain-specific term:
// JSON — multiple top-level keys
{
"name": "Widget",
"price": 9.99,
"inStock": true
}
<!-- XML — wrapped in <product> root -->
<product>
<name>Widget</name>
<price>9.99</price>
<inStock>true</inStock>
</product>Best practice: Structure your JSON with a single top-level key before conversion. This makes the root element deterministic and prevents surprises when different parts of your system convert independently.
3. Basic Property Mapping
JSON key-value pairs map directly to XML child elements. The key becomes the element tag name, and the value becomes the text content. This is the simplest and most common conversion pattern.
// JSON
{
"employee": {
"firstName": "Maria",
"lastName": "Garcia",
"department": "Engineering",
"startDate": "2024-03-15"
}
}
<!-- XML -->
<employee>
<firstName>Maria</firstName>
<lastName>Garcia</lastName>
<department>Engineering</department>
<startDate>2024-03-15</startDate>
</employee>One important consideration: JSON keys can contain characters that aren't valid in XML tag names (spaces, special characters, starting with numbers). If your JSON has keys like "first name" or"2ndAddress", you'll need to sanitize them before conversion. Replace spaces with underscores or camelCase, and ensure tag names start with a letter or underscore.
4. Arrays to Repeated Elements
JSON arrays have no direct XML equivalent. The standard approach is to create repeated sibling elements with the same tag name. Choosing meaningful, singular tag names for array items is important for readability.
Simple value arrays
// JSON
{
"colors": {
"color": ["red", "green", "blue"]
}
}
<!-- XML -->
<colors>
<color>red</color>
<color>green</color>
<color>blue</color>
</colors>Object arrays
Arrays of objects each become a repeating element containing child elements:
// JSON
{
"team": {
"member": [
{ "name": "Alice", "role": "Lead" },
{ "name": "Bob", "role": "Developer" },
{ "name": "Carol", "role": "Designer" }
]
}
}
<!-- XML -->
<team>
<member>
<name>Alice</name>
<role>Lead</role>
</member>
<member>
<name>Bob</name>
<role>Developer</role>
</member>
<member>
<name>Carol</name>
<role>Designer</role>
</member>
</team>Naming convention matters
Use a parent wrapper element (plural) containing child elements (singular): <members> wrapping<member> elements. This makes the XML self-documenting and easier to validate with schemas. Avoid ambiguous names like <item> when a more descriptive name exists.
5. Representing JSON Attributes in XML
When converting JSON to XML, some properties are better represented as XML attributes rather than child elements. The @-prefix convention signals that a JSON property should become an XML attribute:
// JSON with @ prefix for attributes
{
"user": {
"@id": "7",
"@status": "active",
"name": "Taylor",
"email": "taylor@example.com"
}
}
<!-- XML — @-prefixed keys become attributes -->
<user id="7" status="active">
<name>Taylor</name>
<email>taylor@example.com</email>
</user>When to use attributes vs. elements: Use attributes for simple metadata (IDs, status codes, language codes, units) and elements for actual data content. A good rule of thumb: if the value is a short, single-value identifier or qualifier, use an attribute. If it's multi-valued, complex, or likely to be queried independently, use an element.
6. Handling Null, Empty, and Boolean Values
JSON has explicit types for null, booleans, and empty strings. XML has none of these natively — everything is text. You need conventions to preserve this information.
Null values
You have three choices: omit the element entirely, include an empty element, or use an explicit nil attribute from the XML Schema Instance namespace:
// JSON
{ "profile": { "nickname": null } }
<!-- Option 1: Omit the element -->
<profile />
<!-- Option 2: Empty element -->
<profile>
<nickname></nickname>
</profile>
<!-- Option 3: xsi:nil (schema-aware) -->
<profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<nickname xsi:nil="true" />
</profile>Booleans and numbers
JSON booleans (true/false) and numbers are serialized as text in XML. If your XML consumer needs to know the original type, include type hints via attributes or rely on an XSD schema for validation:
// JSON
{ "settings": { "darkMode": true, "fontSize": 14 } }
<!-- XML (values become text) -->
<settings>
<darkMode>true</darkMode>
<fontSize>14</fontSize>
</settings>7. Nested Objects and Deep Hierarchies
Deeply nested JSON objects translate into deeply nested XML elements. While this is structurally valid, consider flattening overly deep hierarchies for readability and XPath query performance.
// JSON — deeply nested
{
"company": {
"departments": {
"department": [
{
"name": "Engineering",
"teams": {
"team": [
{
"name": "Backend",
"lead": "Jordan",
"members": {
"member": ["Alex", "Sam", "Pat"]
}
}
]
}
}
]
}
}
}
<!-- Corresponding XML -->
<company>
<departments>
<department>
<name>Engineering</name>
<teams>
<team>
<name>Backend</name>
<lead>Jordan</lead>
<members>
<member>Alex</member>
<member>Sam</member>
<member>Pat</member>
</members>
</team>
</teams>
</department>
</departments>
</company>8. Generating Valid SOAP Envelopes
One of the most common reasons to convert JSON to XML is to call SOAP web services. SOAP requires a specific XML structure with an Envelope, Header, and Body. Your JSON data becomes the content inside the Body element.
<!-- SOAP envelope wrapping converted JSON data -->
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:svc="http://example.com/service">
<soap:Header>
<svc:AuthToken>abc123</svc:AuthToken>
</soap:Header>
<soap:Body>
<svc:CreateOrder>
<svc:customerId>42</svc:customerId>
<svc:items>
<svc:item>
<svc:sku>WIDGET-01</svc:sku>
<svc:quantity>3</svc:quantity>
</svc:item>
</svc:items>
</svc:CreateOrder>
</soap:Body>
</soap:Envelope>Workflow: First, convert your JSON payload to XML. Then, wrap it inside the SOAP envelope structure with the correct namespace declarations. Most SOAP clients (like Apache CXF, SoapUI, or Zeep for Python) handle envelope wrapping automatically, but understanding the structure helps when debugging integration issues.
9. Building RSS and Atom Feeds from JSON
If your content management system stores articles as JSON, you can generate RSS feeds by converting article data to the RSS XML schema. Here's the mapping:
// JSON article data
{
"articles": [
{
"title": "Understanding API Design",
"link": "https://example.com/api-design",
"description": "A practical guide to RESTful API design.",
"pubDate": "2026-02-15T10:00:00Z"
}
]
}
<!-- RSS 2.0 XML -->
<rss version="2.0">
<channel>
<title>My Blog</title>
<link>https://example.com</link>
<description>Latest articles</description>
<item>
<title>Understanding API Design</title>
<link>https://example.com/api-design</link>
<description>A practical guide to RESTful API design.</description>
<pubDate>Sun, 15 Feb 2026 10:00:00 GMT</pubDate>
</item>
</channel>
</rss>Note that RSS uses RFC 822 date format, not ISO 8601. You'll need to reformat dates during conversion. Also, RSS has specific required elements (title,link,description) that must be present for valid feeds.
10. Code Examples
JavaScript (Node.js with xml2js Builder)
const xml2js = require('xml2js');
const jsonData = {
order: {
$: { id: '1001' }, // $ maps to attributes
customer: 'Alice',
items: {
item: [
{ sku: 'A1', qty: '2' },
{ sku: 'B2', qty: '1' },
]
}
}
};
const builder = new xml2js.Builder({
headless: false,
renderOpts: { pretty: true, indent: ' ' }
});
const xml = builder.buildObject(jsonData);
console.log(xml);Python (with dicttoxml)
import dicttoxml
from xml.dom.minidom import parseString
data = {
"order": {
"customer": "Alice",
"items": [
{"sku": "A1", "qty": 2},
{"sku": "B2", "qty": 1},
]
}
}
xml_bytes = dicttoxml.dicttoxml(data, custom_root='root', attr_type=False)
pretty = parseString(xml_bytes).toprettyxml(indent=" ")
print(pretty)C# (.NET with JsonConvert)
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Xml.Linq;
string json = @"{ ""order"": { ""customer"": ""Alice"" } }";
XNode node = JsonConvert.DeserializeXNode(json);
Console.WriteLine(node.ToString());
// Output:
// <order>
// <customer>Alice</customer>
// </order>11. Validation and Schema Compliance
Generated XML should be validated against a schema when the consumer requires specific structure. This is especially important for SOAP services, EDI exchanges, and regulatory submissions.
- XSD validation: Use XML Schema Definition files to verify element names, types, cardinality, and required attributes. Tools like xmllint, Xerces, and online validators can check compliance.
- Element ordering: XML schemas can enforce element order (via
xs:sequence). JSON objects are unordered, so your converter may produce elements in different orders than the schema expects. Sort elements according to the schema after conversion if needed. - Namespace declarations: Ensure all required namespace prefixes and URIs are declared on the root element. Missing namespace declarations will cause validation failures.
- Required elements: If the schema requires certain elements, verify they exist in your JSON before conversion. Provide default values or raise errors for missing data.
12. Performance Considerations for Large Payloads
XML is more verbose than JSON. A 1 MB JSON file can easily become 2-3 MB of XML due to opening/closing tags and attribute syntax. For large-scale conversions, consider these optimizations:
- Streaming conversion: For files larger than 10MB, use SAX-style or streaming parsers that process elements incrementally rather than loading the entire document into memory.
- Compact formatting: Skip pretty-printing (indentation and newlines) for machine-to-machine communication. This can reduce XML size by 15-25%.
- Compression: Apply gzip or brotli compression to XML payloads during transmission. XML compresses well because of repeated tag names.
- Chunked processing: For batch conversions (e.g., converting 100,000 JSON records to XML), process in chunks of 1,000-5,000 records to manage memory and provide progress feedback.
Try It Yourself
Use our JSON to XML converter to test your JSON payloads instantly. Paste your JSON, click convert, and format the output — all processing happens in your browser.
For the reverse direction, see our XML to JSON guide. To understand when each format is the better choice, read ourXML vs JSON comparison.