How to Convert XML to JSON Without Losing Data
Learn how to convert XML to JSON without losing attributes, text nodes, or array structures, avoid the singleton list trap, and prevent data corruption.
When modernizing legacy systems, ingesting SOAP service responses, parsing RSS feeds, or integrating with enterprise ERP gateways, developers must routinely transform XML documents into JSON. Modern web applications and frontend frameworks like React, Vue, and Node.js operate natively on JSON. However, naive conversions frequently discard attributes, collapse single-element arrays into scalar objects, truncate leading zeros from postal codes, or erase mixed text content.
To preserve the XML values most applications depend on, adopt deterministic conventions: keep attributes under a dedicated prefix such as @, isolate element text with a key such as #text, retain primitive values as strings until explicitly cast, and normalize fields that your schema defines as arrays. A generic XML-to-JSON conversion is not a byte-for-byte reversible transformation because XML also has comments, processing instructions, CDATA boundaries, and ordered mixed content.
You can test and convert any document immediately with ToolPorta's XML to JSON Converter directly in your browser. This technical guide explains why the XML and JSON data models clash, presents a battle-tested 5-step conversion workflow, details solutions for the "singleton array" trap and attribute collisions, analyzes security concerns like XML External Entity (XXE) attacks, and compares both formats in an architectural reference table.
Why converting XML to JSON causes data loss#
XML and JSON were invented with different goals, creating an architectural impedance mismatch when converting from one to the other.
XML, defined by the W3C Extensible Markup Language 1.0 Specification, was designed as an extensible document markup language capable of handling structured records, narrative prose, and metadata simultaneously. JSON, defined under RFC 8259, was designed as a minimal, language-agnostic data interchange format strictly modeling key-value pairs and arrays.
Data loss occurs during conversion because XML possesses structural concepts that JSON lacks:
- Attributes vs. Child Elements: In XML, an element can store information both as attributes within its opening tag (
<transaction id="tx_99" status="cleared">) and as nested child elements (<amount>450.00</amount>). JSON objects only have uniform key-value pairs. If a converter ignores attributes, critical metadata vanishes. - Ambiguous List Semantics (The Array Problem): XML has no native list syntax. A list is represented simply by repeating sibling tags:
<item>A</item><item>B</item>. When an XML list contains only one item (<item>A</item>), naive parsers cannot tell whether<item>was intended to be an array or a single property. - Mixed Content and Inner Text: An XML element can contain both raw character data and child tags within the same scope:
<note>Payment received on <date>2026-10-01</date> via wire.</note>. In JSON, a key's value must be either a string, a number, a boolean, an array, or an object—it cannot be a hybrid of a string and an object. - Typeless Text Values: XML stores all tag values as raw character strings. If a converter naively infers numbers, values like the Boston ZIP code
"02138"are coerced into the integer2138, permanently destroying the leading zero. - Namespaces and Prefixes: XML uses namespaces (
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/") to avoid tag collisions across distributed schemas. Converting without namespace awareness causes tag collisions or strips critical context.
How to convert XML to JSON step by step#
To protect the integrity of production data, follow a disciplined 5-step conversion pipeline.
Step 1: Validate XML syntax and structural well-formedness#
An XML parser cannot process malformed markup. If tags are unclosed, attribute quotes are mismatched, or illegal entity characters exist, parsing terminates immediately.
Before conversion, confirm that your XML is well-formed according to W3C standards: every opening tag must have a matching closing tag, and special characters must be properly escaped (&, <, >).
Step 2: Establish an attribute preservation strategy#
To prevent attributes from disappearing or overwriting child tags with the same name, use a dedicated attribute prefix convention. The standard industry approach prefixes attribute names with an @ character:
When converted with attribute preservation:
This guarantees that an attribute named name="Widget" will never collide with a child element named <name>Widget</name>.
Step 3: Handle inner text with dedicated text node keys#
When an XML element contains both attributes and direct text content, map the text content to a reserved property name, typically #text:
Converting this node yields a clean, unambiguous JSON object:
If an element has no attributes and only contains text (e.g., <name>Alice</name>), it simplifies directly to a standard string property: "name": "Alice".
Step 4: Configure type inference carefully#
Determine whether your application requires raw string retention or primitive type inference:
- String retention (safest for scalar spelling): Values such as
"@id": "0123"and"active": "true"remain strings. This preserves leading zeros and avoids numeric rounding, although whitespace trimming and XML-only constructs still require separate decisions. - Type Inference: Converts
"true"totrueand"42"to42. Only enable this if your dataset does not contain telephone numbers, postal codes, or identifiers that look like numbers.
Step 5: Format and inspect the resulting JSON#
Once the JSON is produced, verify that all nested hierarchies, lists, and metadata tags are mapped properly. You can paste the output into ToolPorta's JSON Formatter to inspect the structure with clean indentation, or use the JSON Validator to ensure compliance with RFC 8259.
Realistic before-and-after conversion example#
Consider a realistic XML response from an enterprise warehouse logistics service, containing attributes, single and multiple sibling elements, leading zeros, and namespace declarations:
When converted with attributes preserved, namespace prefixes maintained, type inference disabled, and the default value trimming enabled, ToolPorta preserves the values and structures used in this example:
Notice that:
- The leading zero in
<facilityCode>00482</facilityCode>and the ZIP code"02138"are completely intact. - The weight element cleanly isolates both the
@unitattribute and#textvalue"4.25". - The repeated
<item>elements vectorized automatically into a standard JSON array. - The
geo:namespace qualifier was preserved to avoid property name collisions.
Common pitfalls and edge cases that cause data loss#
Understanding the most common failure modes helps you prevent silent regressions in backend data pipelines.
1. The "Singleton Array" trap#
The most notorious bug in XML-to-JSON conversion is the singleton array problem.
When an XML list contains two or more sibling elements, parsers naturally create an array:
However, if an XML feed returns only one item:
Downstream frontend code expecting an array will execute data.tags.tag.map(...) or data.tags.tag.forEach(...), triggering a fatal runtime error: TypeError: data.tags.tag.map is not a function.
The Fix: In production backend systems, use parsers with schema awareness or post-process the resulting JSON with a normalization helper that guarantees properties expected to be collections always evaluate to an array:
For programmatic implementations, review our JavaScript XML to JSON guide or equivalent Python conversion examples.
2. Accidental type coercion and truncated identifiers#
Naive converters attempt to convert string values like "1234" or "007" into numeric primitives. This causes three types of irreversible data corruption:
- Stripped Leading Zeros: Account numbers, SWIFT codes, barcode numbers, and postal codes like
"0042"become42. - 64-Bit Integer Truncation: Distributed database keys (such as Snowflake IDs like
1840829837492817283) exceed JavaScript'sNumber.MAX_SAFE_INTEGER(2^53 - 1) and lose their final digits when cast into floating-point numbers. - Boolean Confusion: Certain codes like
"N"or"0"may be misinterpreted as booleanfalse.
The Fix: Keep type inference disabled by default when ingesting third-party or financial XML feeds. Parse values as strings and selectively cast them only within your business logic.
3. Mixed content stripping#
In document-centric XML (such as DITA, DocBook, or XHTML), tags often embed inline markup within sentences:
A naive parser will either discard the text "System status is" or flatten the entire element into a single string "System status is Operational as of today.", permanently deleting the <status> tag and its code="ok" attribute.
The Fix: If order within narrative mixed content matters, use an order-aware document parser or a representation that records every text and element node in sequence. CDATA alone does not solve the mapping problem; ToolPorta reads CDATA content as ordinary text and does not retain the CDATA boundary.
4. Stripping XML namespaces#
In enterprise web services (such as SOAP or XML Signature), identical tag names often exist across different namespaces:
If the converter strips namespace prefixes, both tags collide under the single key "name", causing one to overwrite the other. Always preserve namespace prefixes when converting enterprise or multi-vendor XML payloads.
XML vs JSON data model comparison#
| Feature | XML (W3C Standard) | JSON (RFC 8259) | Lossless Conversion Strategy |
|---|---|---|---|
| Structural Units | Elements, attributes, text nodes, comments, processing instructions | Objects ({}) and arrays ([]) | Map attributes and text explicitly; decide whether XML-only nodes may be dropped |
| List Representation | Sibling tags with identical names | Ordered arrays wrapped in [] | Vectorize repeated tags; normalize singletons |
| Attributes Support | Native in opening tag (<tag k="v">) | Not supported (keys are uniform) | Use an attribute prefix to prevent property collisions |
| Data Types | Everything is character text | String, Number, Boolean, Null, Array, Object | Keep strings intact to prevent number truncation |
| Root Requirement | Strictly one enclosing root tag | Any single JSON value | The XML root tag becomes the top-level JSON key |
| Mixed Content | Preserves ordered text and child nodes | Has no standard XML node model | Requires an order-aware custom representation |
| Namespace Support | Built-in (xmlns:prefix) | Unsupported natively | Retain prefixes as part of the JSON property key |
| Document Size | Often has more markup | Often has less markup | Compare and compress representative payloads instead of assuming a fixed advantage |
Frequently asked questions#
How do I handle XML elements that contain both attributes and text?#
The standard industry convention is to map attributes with an @ prefix (e.g., "@id": "42") and store the direct text content under a reserved key, typically "#text". For example, <amount currency="USD">99.50</amount> becomes {"amount": {"@currency": "USD", "#text": "99.50"}}. ToolPorta's converter applies this mapping automatically.
Why did my single-item XML list convert to an object instead of an array?#
In XML, there is no structural difference between an element that happens to be repeated and an element that appears only once. When a parser encounters a single <item> tag, it cannot know whether it is part of a list without a schema. To avoid breaking downstream code that calls .map(), check whether the property is an array and wrap it in [value] if it is not.
Should I enable automatic type inference when converting XML to JSON?#
Only enable type inference if your XML payload contains standard numbers and booleans that do not require leading zero preservation. If your dataset includes ZIP codes, phone numbers, UUIDs, or large 64-bit database identifiers, keep type inference disabled to prevent data corruption.
Try the related ToolPorta tools#
Converting XML documents into clean, idiomatic JSON simplifies application development and accelerates API integrations. ToolPorta provides a comprehensive suite of browser-based utilities to streamline your data pipelines:
- Use the XML to JSON Converter to transform XML feeds and SOAP payloads into structured JSON instantly.
- Use the JSON to XML Converter when you need to serialize JSON models back into compliant XML documents.
- Use the JSON Formatter to organize, inspect, and beautify your converted JSON.
- Use the JSON Validator to ensure your JSON conforms strictly to RFC 8259 syntax.
- Explore our JavaScript XML to JSON guide for production-grade code examples.