Skip to main content
SnipKit
XML to JSON: What Actually Changes (and the Gotchas to Watch For)

Photo by David Clode on Unsplash

XML to JSON: What Actually Changes (and the Gotchas to Watch For)

SnipKit Team5 min read

You have XML in hand — a SOAP response, an RSS feed, an old config — and you need JSON for a modern stack. The xml to json conversion is almost lossless, but there's a short list of places where data changes shape or quietly disappears. Know those spots before you ship. SnipKit's converter handles the mechanics in-browser; this article explains what it's actually doing.

When Conversion Actually Comes Up

Most of this work falls into four situations:

  • SOAP API modernization. A modern frontend needs to talk to a backend that returns XML SOAP envelopes. Strip the envelope, convert the body to JSON.
  • RSS and Atom feeds in JavaScript. JSON lets you map over items with array methods instead of wrestling with the DOM.
  • Config file migration. Maven pom.xml, AndroidManifest.xml, legacy Spring configs — all moving toward JSON-based tooling.
  • Enterprise data pipelines. EDI feeds, ERP exports, and vendor XML dumps. Convert at ingestion, normalize types, then insert into Postgres or MongoDB.

The Conversion Rules in Plain English

These rules are consistent across major libraries — knowing them means you can predict the output shape before running anything.

Attributes become keys prefixed with @. SnipKit uses @ (the xml2js default); alternatives you'll meet include _attr and $.attr. The prefix prevents collisions — without it, an attribute id and a child <id> would overwrite each other.

<user id="42" role="admin">Alice</user>
{
  "user": {
    "@id": "42",
    "@role": "admin",
    "#text": "Alice"
  }
}

Repeated sibling elements become a JSON array. Two or more <item> siblings produce an array, while a single <item> produces an object. This asymmetry causes the biggest gotcha — more below.

<items>
  <item>Alpha</item>
  <item>Beta</item>
</items>
{
  "items": {
    "item": ["Alpha", "Beta"]
  }
}

Text content becomes a string. Elements with no attributes or children map directly to a string value; with attributes or children alongside text, the text lands in a #text key (see the <user> example above).

CDATA sections become transparent strings. <![CDATA[<raw markup>]]> is unwrapped to its content — the wrapper disappears.

Comments and processing instructions are dropped. They have no JSON equivalent.

The Four Gotchas to Watch For

1. Array Ambiguity

The most common production surprise. A single <item> child and a pair of <item> children look identical to the XML parser but produce different JSON shapes.

<items><item>A</item></items>

produces "item": "A" (string), while adding <item>B</item> produces "item": ["A", "B"] (array). Either handle both shapes downstream, or use a converter option that forces single elements into arrays (often explicitArray: true).

2. Type Loss

XML has no native number, boolean, or null — everything is text. So <count>30</count> becomes "count": "30" (a string), and you'll need to cast numeric fields explicitly after conversion before any math or DB insertion.

3. Attribute Key Collisions

The @ prefix keeps an attribute id and a child <id> as separate keys; without it they collide. Consumers expecting clean unprefixed keys, however, will choke on @id. Decide your attribute strategy before conversion.

4. Namespaces and Prefixes

Namespace-prefixed names like xsi:type, soap:Envelope, and xmlns:ns0 become literal JSON keys. A consumer expecting "type" won't find "xsi:type". Strip, rewrite, or preserve namespaces intentionally.

Real Examples

SOAP Response Fragment

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetOrderResponse>
      <orderId>9021</orderId>
      <status>shipped</status>
      <total>149.99</total>
    </GetOrderResponse>
  </soap:Body>
</soap:Envelope>
{
  "soap:Envelope": {
    "@xmlns:soap": "http://schemas.xmlsoap.org/soap/envelope/",
    "soap:Body": {
      "GetOrderResponse": {
        "orderId": "9021",
        "status": "shipped",
        "total": "149.99"
      }
    }
  }
}

The namespace prefix survives as a literal key, and total is the string "149.99", not a number.

RSS Feed Item

<item>
  <title>New Feature: Dark Mode</title>
  <link>https://example.com/dark-mode</link>
  <pubDate>Sun, 24 May 2026 09:00:00 GMT</pubDate>
  <description>Dark mode is now available for all users.</description>
</item>
{
  "item": {
    "title": "New Feature: Dark Mode",
    "link": "https://example.com/dark-mode",
    "pubDate": "Sun, 24 May 2026 09:00:00 GMT",
    "description": "Dark mode is now available for all users."
  }
}

Clean and flat — no attributes, no repeated elements, JSON matches intuition exactly. Pretty-print noisy feed XML first with the XML Formatter.

After Conversion: 5-Point Verification

Before using the output in production:

  • Cast numeric strings. "149.99" should become 149.99 before any math or DB insertion.
  • Normalize arrays. Decide once whether single-child elements are arrays or scalars, then enforce it everywhere.
  • Search for #text. An element you thought was flat may have attributes, triggering the #text split.
  • Verify your attribute prefix. Match what downstream expects — strip the @ or keep it.
  • Handle namespaces deliberately. Pick one approach (keep, strip, rewrite) before downstream code is written.

Pretty-print the result with the JSON Formatter and confirm syntax with the JSON Validator.

FAQ

Does XML to JSON conversion lose data?

Element content and attributes survive. What's dropped: XML comments, processing instructions, and type information (everything becomes a string). Mixed-content ordering can also be mangled by some implementations. For typical data XML, conversion is effectively lossless.

What happens to XML attributes when converting to JSON?

Attributes become keys with an @ prefix in most modern libraries, including SnipKit's XML to JSON converter. The prefix prevents collisions with child element keys of the same name. Strip or rename it after conversion if your consumer expects clean keys.

Can I round-trip XML to JSON to XML safely?

Usually not. Array ambiguity and type loss mean the reconstructed XML won't be identical to the original. If you need reliable round-tripping, use a schema-aware mapping layer, not a generic converter. The JSON to XML guide covers the reverse direction.

Conclusion

The rules are simple and learnable in an afternoon, but the gotchas — array ambiguity, type loss, attribute collisions, and namespace bleed-through — are what catch teams in production. Verify after every conversion. Paste your XML into SnipKit's xml to json converter for instant client-side output, or jump to JSON to XML for the reverse direction.

Related Articles