9 min read

How to Convert JSON to XML

Learn how to convert JSON to clean, well-formed XML, map objects and arrays to XML elements and attributes, and avoid common schema pitfalls.

Modern web APIs, cloud microservices, and JavaScript frontend applications exchange data almost exclusively in JSON. However, enterprise systems, banking gateways, healthcare standards (like HL7/FHIR), government web services, SOAP endpoints, and RSS/Atom feeds still require XML. When connecting modern application stacks with legacy infrastructure, developers frequently need to translate JSON data models into well-formed XML documents.

To convert JSON to XML properly, you cannot simply swap curly braces for angled brackets. You must map JSON key-value pairs into an XML document tree, enclose the structure within a single root element, establish rules for element attributes versus child nodes, and vectorize arrays with explicit tag names.

You can convert any payload immediately using ToolPorta's JSON to XML Converter directly in your browser. This technical guide explains the structural differences between JSON and XML, outlines a reliable 5-step conversion workflow, demonstrates how to handle attributes, arrays, and null values, highlights critical edge cases like invalid element names and XML injection, and compares the two data formats side by side.

What converting JSON to XML actually involves#

JSON (JavaScript Object Notation) and XML (Extensible Markup Language) represent data using fundamentally different information models. Understanding these distinctions is essential for designing clean conversion pipelines.

JSON, specified under RFC 8259, is a lightweight serialization format organized around two structural primitives:

  • Objects: Unordered collections of name-value pairs wrapped in {}.
  • Arrays: Ordered sequences of zero or more values wrapped in [].

JSON natively distinguishes between string literals, floating-point numbers, booleans, and null values.

XML, specified by the W3C Extensible Markup Language (XML) 1.0 Recommendation, is a markup language designed for hierarchical document trees. Unlike JSON, XML introduces several structural constructs that do not have direct 1:1 counterparts in JSON:

  1. The Single Root Element Rule: Every well-formed XML document must contain exactly one root element that encloses all other tags. A JSON payload with multiple top-level keys or a top-level array cannot become valid XML without a wrapper element (such as <root>).
  2. Attributes vs. Child Elements: XML elements can contain attributes within their opening tag (<user id="42" status="active">) in addition to nested child elements (<name>Alice</name>). JSON objects only have key-value pairs.
  3. Repeated Sibling Elements for Arrays: JSON models a collection as an array: "tags": ["admin", "developer"]. In XML, there is no generic "array" wrapper; instead, lists are represented as repeated sibling elements (<tag>admin</tag><tag>developer</tag>) or nested inside a parent element (<tags><item>admin</item><item>developer</item></tags>).
  4. Typeless Text Content: In XML, all element content and attribute values are character sequences (strings). Numerical precision (42.50) and booleans (true) lose their native programming types unless governed by an explicit XML Schema Definition (XSD) or metadata attributes.
  5. Mixed Content: XML elements can interleave text and child tags (such as <p>Click <a href="/">here</a> to proceed.</p>). Standard JSON cannot represent mixed content without custom object wrappers.

To bridge these differences, conversion tools adopt conventional mapping rules, such as using an @ prefix for attributes (e.g., "@id": "42") and #text for inner element text.

How to convert JSON to XML step by step#

Following a systematic conversion workflow helps produce well-formed XML. Passing an XSD or another downstream schema is a separate requirement: the element names, order, namespaces, and types must match that schema.

Step 1: Validate and format source JSON#

Before initiating any transformation, ensure that the source JSON is syntactically sound. If the JSON contains unquoted keys, single quotes, or trailing commas, the parser will fail immediately.

Paste the payload into ToolPorta's JSON Validator to locate syntax errors, or use the JSON Formatter to inspect the object hierarchy.

Step 2: Establish the enclosing root element#

Because XML mandates a single root node, determine the appropriate root tag for your business context. If your JSON represents a customer record, use <customer> or <account> rather than a generic <root> tag:

JSON
1{2  "customer": {3    "name": "Acme Corp",4    "status": "active"5  }6}

If your JSON input has multiple top-level properties or begins with an array, configure your converter to wrap the generated output inside an explicit root tag.

Step 3: Define attribute mapping conventions#

Decide whether specific object properties should render as XML attributes or child elements. In high-interoperability workflows:

  • Use attributes for metadata, unique identifiers, timestamps, and status codes.
  • Use child elements for rich text, nested objects, and business data.

Using the widely recognized @ prefix convention:

JSON
1{2  "invoice": {3    "@currency": "USD",4    "@id": "INV-2026-001",5    "total": .6  }7}

converts directly into:

XML
1<invoice currency="USD" id="INV-2026-001">2  <total></total>3</invoice>

Step 4: Vectorize arrays and choose item tags#

XML does not have native square brackets. When converting a JSON array, you must assign a repeating tag name to each element. For example, converting "roles": ["admin", "editor"] can yield:

XML
1<roles>2  <item>admin</item>3  <item>editor</item>4</roles>

Alternatively, configuring an explicit item tag (such as <role>) provides cleaner semantics for downstream systems.

Step 5: Configure null value and self-closing tag handling#

In JSON, null represents the absence of a value. In XML, you must choose how null values should be serialized:

  • Self-closing tag (Recommended): Render {"email": null} as <email/>.
  • Omission: Remove the tag entirely from the XML document.
  • Explicit nil attribute: Use the XML Schema instance namespace (xsi:nil="true").

Realistic before-and-after conversion example#

Consider a customer shipment payload containing metadata attributes, nested items, formatted notes, and null values:

JSON
1{2  "order": {3    "@id": "ORD-94821",4    "@created": "2026-10-01",5    "customer": {6      "name": "Global Logistics LLC",7      "accountTier": "enterprise"8    },9    "lineItems": [10      {11        "sku": "NET-SW-48P",12        "quantity": ,13        "unitPrice": .14      },15      {16        "sku": "SFP-10G-LR",17        "quantity": ,18        "unitPrice": .19      }20    ],21    "specialInstructions": "Deliver to Dock B between 08:00 & 16:00.",22    "cancellationReason": null23  }24}

When converted through ToolPorta with 2-space indentation, self-closing empty elements, and the root option left blank so the existing order key becomes the document root, it yields well-formed XML:

XML
1<?xml version="1.0" encoding="UTF-8"?>2<order id="ORD-94821" created="2026-10-01">3  <customer>4    <name>Global Logistics LLC</name>5    <accountTier>enterprise</accountTier>6  </customer>7  <lineItems>8    <item>9      <sku>NET-SW-</sku>10      <quantity></quantity>11      <unitPrice></unitPrice>12    </item>13    <item>14      <sku>SFP--LR</sku>15      <quantity></quantity>16      <unitPrice></unitPrice>17    </item>18  </lineItems>19  <specialInstructions>Deliver to Dock B between : &amp; :.</specialInstructions>20  <cancellationReason/>21</order>

Notice that the ampersand (&) in the delivery instructions was automatically escaped as &amp; to maintain XML well-formedness, the array items were vectorized as <item> elements, and the null field was converted into a self-closing <cancellationReason/> tag.

Common errors, edge cases, and how to fix them#

Converting JSON to XML exposes several structural incompatibilities. Overlooking these edge cases can cause downstream XML parsers, SOAP endpoints, or XSD validators to reject the output.

1. Invalid XML element and attribute names#

JSON permits virtually any valid Unicode string as an object key, including keys that start with numbers, contain spaces, or feature punctuation marks:

JSON
1{2  "123order": "invalid-xml-tag",3  "first name": "invalid-space",4  "$schema": "invalid-symbol"5}

Under Section 2.3 of the W3C XML specification, element and attribute names must follow strict naming grammar:

  • An XML name must start with a letter, an underscore (_), or a colon (:). It cannot start with a digit, a hyphen (-), or a period (.).
  • Subsequent characters can include letters, digits, hyphens, underscores, and periods.
  • Names cannot contain spaces, commas, slashes, or currency symbols like $.

The Fix: When converting JSON with arbitrary keys, sanitize invalid names by prefixing non-conforming starting characters with an underscore (e.g., _123order) and replacing whitespace or disallowed symbols with underscores (first_name). ToolPorta's converter includes automatic name sanitization options.

2. Missing root element with top-level JSON arrays#

A frequent error occurs when converting a JSON payload whose root is an array:

JSON
1[2  { "id": , "name": "Item A" },3  { "id": , "name": "Item B" }4]

Attempting to serialize this directly into XML results in multiple sibling root elements:

XML
1<!-- INVALID: Violates the W3C single-root requirement -->2<item><id></id><name>Item A</name></item>3<item><id></id><name>Item B</name></item>

XML parsers will terminate with XML Parsing Error: junk after document element.

The Fix: Always configure an enclosing root wrapper (such as <items> or <root>) so the output has a single parent tag:

XML
1<!-- VALID -->2<items>3  <item><id></id><name>Item A</name></item>4  <item><id></id><name>Item B</name></item>5</items>

3. Unescaped predefined XML entities#

JSON strings only require escaping for double quotes ("), backslashes (\), and ASCII control characters (\u0000 to \u001F). Characters like <, >, and & are completely valid within JSON strings:

JSON
1{ "query": "price < 50 && stock > 0" }

In XML, < and & are strictly reserved characters for element tags and entity declarations. If left unescaped, the XML parser interprets < 50 as the start of an illegal tag and crashes.

The Fix: All text values must convert predefined characters into their respective XML entity references:

  • & becomes &amp;
  • < becomes &lt;
  • > becomes &gt;
  • " (in attributes) becomes &quot;
  • ' (in attributes) becomes &apos;

Alternatively, wrap large blocks of arbitrary code or Markdown in a <![CDATA[ ... ]]> section.

4. Loss of primitive data types#

In XML, all values between tags are parsed as strings unless governed by an explicit XSD schema. When converting {"count": 42, "active": true} into <count>42</count><active>true</active>, downstream consumers written in dynamically typed languages may read "42" and "true" as raw text.

The Fix: If downstream systems require explicit typing, enrich the XML output with XML Schema instance attributes:

XML
1<count xsi:type="xs:integer"></count>2<active xsi:type="xs:boolean">true</active>

When building automated backend pipelines, inspect our JavaScript JSON to XML guide or Python conversion examples for type-safe serialization code.

JSON vs XML: Data model comparison#

FeatureJSON (RFC 8259)XML (W3C Recommendation)Conversion Consideration
Data StructureKey-value objects and indexed arraysHierarchical element and document treeRequires mapping arrays to repeated sibling tags
Root NodeAny single value (object, array, string, number)Strictly one root elementArrays and multiple keys require an enclosing <root> wrapper
AttributesNot supported (keys are uniform)Supported in opening tag (<tag attr="val">)Requires a prefix convention (such as @attr)
Native TypesString, Number, Boolean, Array, Object, NullOnly text nodes and attribute stringsNumerical and boolean types become text content
Schema ValidationJSON Schema (lightweight, optional)XSD, DTD, RelaxNG (strict, comprehensive)XML schemas frequently enforce element ordering and namespaces
CommentsDisallowed in standard JSONSupported (<!-- comment -->)Stripped or lost during bidirectional conversion
Payload SizeUsually less markup overheadOften larger because of element names and closing tagsUse an XML-aware serializer or transport compression for XML
NamespacesNo built-in namespace mechanismSupported via xmlns:prefixEssential for enterprise SOAP and enterprise schemas

Frequently asked questions#

Can I convert a JSON array to XML without an enclosing root element?#

No. A well-formed XML document must contain exactly one document element. A top-level JSON array therefore needs a wrapper such as <items>, with each array value represented by a child element.

How do I represent XML attributes in JSON?#

The most widely adopted convention is to prefix attribute property names with an @ symbol. For example, {"user": {"@id": "101", "name": "Sarah"}} converts into <user id="101"><name>Sarah</name></user>. ToolPorta's converter supports this @ prefix convention by default.

What happens to JSON null values during XML conversion?#

Because XML does not have a native null keyword, null values can be handled in three ways: rendered as a self-closing element (<field/>), omitted entirely from the document, or marked with an explicit XML Schema instance attribute (<field xsi:nil="true"/>). ToolPorta defaults to clean self-closing tags.

Converting between structured data formats is a fundamental step when connecting modern web architectures with enterprise systems. ToolPorta provides a comprehensive set of browser-based utilities to help you manage your data: