Introduction

XML (eXtensible Markup Language) was the standard for data exchange in the 2000s, but JSON has taken over in modern applications. If you’re working with legacy systems or APIs that use XML, you may need to migrate to JSON.

Why Migrate from XML to JSON?

XML: The Old Standard

XML was designed for:

  • Document structures
  • Metadata and attributes
  • Complex validation with XSD schemas
  • Transformations with XSLT

JSON: The Modern Standard

JSON is better for:

  • Simpler syntax: Less verbose
  • Faster parsing: Native support in JavaScript
  • Smaller file size: ~30-40% smaller
  • Better performance: 3-5x faster to parse
  • Web-first: Perfect for REST APIs

Comparison: XML vs JSON

XML Example

<?xml version="1.0" encoding="UTF-8"?>
<users>
  <user id="1" active="true">
    <name>Alice</name>
    <email>alice@example.com</email>
    <address>
      <street>123 Main St</street>
      <city>Stockholm</city>
    </address>
    <hobbies>
      <hobby>reading</hobby>
      <hobby>coding</hobby>
    </hobbies>
  </user>
  <user id="2" active="true">
    <name>Bob</name>
    <email>bob@example.com</email>
  </user>
</users>

JSON Equivalent

{
  "users": [
    {
      "id": "1",
      "active": true,
      "name": "Alice",
      "email": "alice@example.com",
      "address": {
        "street": "123 Main St",
        "city": "Stockholm"
      },
      "hobbies": ["reading", "coding"]
    },
    {
      "id": "2",
      "active": true,
      "name": "Bob",
      "email": "bob@example.com"
    }
  ]
}

File size: XML: 456 characters, JSON: 299 characters (34% smaller)

Migration Strategies

1. Direct Conversion

Simple 1:1 conversion where XML elements map to JSON objects.

XML:

<product id="123">
  <name>Widget</name>
  <price>29.99</price>
</product>

JSON:

{
  "product": {
    "id": "123",
    "name": "Widget",
    "price": 29.99
  }
}

2. Flattened Structure

Simplify the structure for easier access.

XML:

<user>
  <profile>
    <personal>
      <name>Alice</name>
    </personal>
  </profile>
</user>

JSON (flattened):

{
  "user": {
    "name": "Alice"
  }
}

3. Array Normalization

Convert repeated elements to arrays.

XML:

<items>
  <item>Apple</item>
  <item>Banana</item>
  <item>Orange</item>
</items>

JSON:

{
  "items": ["Apple", "Banana", "Orange"]
}

Handling XML Features

XML Attributes

XML attributes can be handled in several ways:

Method 1: As properties

{
  "user": {
    "id": "1",
    "active": true,
    "name": "Alice"
  }
}

Method 2: Separated metadata

{
  "user": {
    "name": "Alice",
    "_attributes": {
      "id": "1",
      "active": true
    }
  }
}

Recommendation: Use method 1 if possible - simpler and cleaner.

XML Namespaces

XML namespaces can be mapped to prefixed keys:

XML:

<root xmlns:app="http://example.com/app">
  <app:user>Alice</app:user>
</root>

JSON:

{
  "app:user": "Alice"
}

Or use namespace objects:

{
  "namespaces": {
    "app": "http://example.com/app"
  },
  "app:user": "Alice"
}

CDATA Sections

CDATA in XML can be converted directly to strings in JSON:

XML:

<description><![CDATA[Text with <tags> & special chars]]></description>

JSON:

{
  "description": "Text with <tags> & special chars"
}

XML Comments

XML comments can:

  • Be ignored (recommended)
  • Be stored as metadata
  • Be documented separately

Practical Examples

SOAP API to REST API

Before (SOAP/XML):

<soap:Envelope>
  <soap:Body>
    <GetUserRequest>
      <UserId>123</UserId>
    </GetUserRequest>
  </soap:Body>
</soap:Envelope>

After (REST/JSON):

{
  "userId": 123
}

API Call:

// Before: POST /soap/UserService
const xmlBody = `...`;

// After: GET /api/users/123
const response = await fetch("/api/users/123");
const user = await response.json();

RSS Feed to JSON

XML (RSS):

<rss>
  <channel>
    <item>
      <title>Article</title>
      <pubDate>Mon, 07 Dec 2024</pubDate>
    </item>
  </channel>
</rss>

JSON:

{
  "channel": {
    "items": [
      {
        "title": "Article",
        "pubDate": "Mon, 07 Dec 2024"
      }
    ]
  }
}

Conversion with Tools

Programmatic Conversion

JavaScript:

import { XMLParser, XMLBuilder } from "fast-xml-parser";

const parser = new XMLParser({
  ignoreAttributes: false,
  attributeNamePrefix: "@_",
});

const xml = '<user id="1">Alice</user>';
const json = parser.parse(xml);
// { user: { '@_id': '1', '#text': 'Alice' } }

Python:

import xml.etree.ElementTree as ET
import json

def xml_to_dict(element):
    result = {element.tag: {}}
    if element.attrib:
        result[element.tag].update(element.attrib)
    if element.text:
        result[element.tag]['#text'] = element.text
    for child in element:
        result[element.tag].update(xml_to_dict(child))
    return result

xml = ET.parse('data.xml')
json_data = json.dumps(xml_to_dict(xml.getroot()))

Use Our Tools

Best Practices for Migration

1. Schema Validation

// Define JSON Schema for validation
const schema = {
  type: "object",
  properties: {
    users: {
      type: "array",
      items: {
        type: "object",
        properties: {
          id: { type: "string" },
          name: { type: "string" },
        },
        required: ["id", "name"],
      },
    },
  },
};

2. Backwards Compatibility

Consider supporting both formats during transition:

app.post("/api/data", async (req, res) => {
  const contentType = req.headers["content-type"];

  if (contentType.includes("application/xml")) {
    // Convert XML to JSON
    const json = xmlToJson(req.body);
    return processJson(json);
  }

  // Direct JSON
  return processJson(req.body);
});

3. Versioning

Version your API for smooth migration:

/api/v1/data  (XML)
/api/v2/data  (JSON)

4. Testing

Test the conversion thoroughly:

describe("XML to JSON conversion", () => {
  it("should preserve all data", () => {
    const xml = '<user id="1">Alice</user>';
    const json = convertXMLToJSON(xml);

    expect(json.user["@_id"]).toBe("1");
    expect(json.user["#text"]).toBe("Alice");
  });

  it("should handle nested structures", () => {
    const xml = "<root><child><grandchild>value</grandchild></child></root>";
    const json = convertXMLToJSON(xml);

    expect(json.root.child.grandchild).toBe("value");
  });
});

Common Challenges

1. Attribute vs Elements

Problem: XML uses both attributes and elements for data.

Solution: Standardize to one approach - prefer properties.

2. Mixed Content

XML:

<p>This is <strong>bold</strong> text.</p>

JSON:

{
  "p": {
    "text": "This is ",
    "strong": "bold",
    "textAfter": " text."
  }
}

Or use HTML:

{
  "p": "This is <strong>bold</strong> text."
}

3. Namespaces

Problem: XML namespaces can be complex.

Solution: Use prefixed keys or namespace objects.

Conclusion

Migration from XML to JSON is often necessary for modern applications:

When to migrate:

  • Building new APIs
  • Modernizing legacy systems
  • Improving performance
  • Integrating with modern frameworks

When XML might be better:

  • Document structures (Word, PDF)
  • Complex validation (XSD)
  • Transformation pipelines (XSLT)

Use our tools to easily convert between formats and test your migration.

Next Steps