JSONYAMify

Home / Blog / XML ke JSON

Cara Konversi XML ke JSON: Panduan dan Hal yang Perlu Diwaspadai

Oleh Andi Putra Ogie · Update: Juli 2026 · 9 menit baca

Banyak tim yang bekerja dengan sistem legacy berbasis XML (SOAP web service, feed data lama, atau sistem enterprise) suatu saat perlu mengonversi datanya ke JSON supaya kompatibel dengan frontend modern atau REST API baru. Sayangnya, konversi XML ke JSON tidak sesederhana yang dibayangkan — karena XML dan JSON punya model data yang secara fundamental berbeda, ada beberapa keputusan desain yang harus dibuat secara sadar, bukan cuma "auto-convert" dan berharap hasilnya benar.

Kenapa Konversi Ini Tidak Straightforward?

XML dirancang untuk dokumen dengan struktur fleksibel: elemen bisa punya attribute, teks campuran dengan tag lain (mixed content), dan tidak ada konsep array bawaan. JSON dirancang untuk data terstruktur dengan tipe yang jelas: object, array, string, number, boolean, null. Perbedaan model ini berarti tidak ada satu aturan konversi tunggal yang "benar" — semua tool konversi harus membuat asumsi, dan asumsi itu bisa berbeda antar tool. Memahami hal ini sejak awal membantu kamu tidak kaget kalau dua tool konversi berbeda menghasilkan struktur JSON yang tidak identik dari input XML yang sama persis.

Aturan Dasar Mapping Elemen

Konversi paling dasar: elemen XML tanpa attribute dan tanpa child menjadi key-value string sederhana:

<!-- XML -->
<name>Sarah Amelia</name>
// JSON
{ "name": "Sarah Amelia" }

Elemen dengan child element menjadi nested object:

<!-- XML -->
<person>
  <name>Sarah Amelia</name>
  <age>29</age>
</person>
// JSON
{
  "person": {
    "name": "Sarah Amelia",
    "age": "29"
  }
}

Perhatikan age tetap jadi string "29", bukan number 29 — karena XML tidak punya tipe data bawaan, semua nilai defaultnya text. Tool konversi yang lebih pintar bisa mendeteksi dan mengonversi ke number/boolean secara otomatis, tapi ini opsional dan tidak semua tool melakukannya.

Masalah #1: Array vs Single Element

Ini jebakan paling terkenal dalam konversi XML ke JSON. XML tidak punya konsep array eksplisit — elemen berulang cuma "elemen dengan nama sama muncul beberapa kali":

<!-- XML dengan 2 item -->
<books>
  <book>Laskar Pelangi</book>
  <book>Bumi Manusia</book>
</books>

<!-- XML dengan 1 item -->
<books>
  <book>Laskar Pelangi</book>
</books>

Konversi naif akan menghasilkan array untuk kasus pertama, tapi object tunggal untuk kasus kedua:

// Kasus 1 — jadi array
{ "books": { "book": ["Laskar Pelangi", "Bumi Manusia"] } }

// Kasus 2 — jadi object tunggal, BUKAN array satu elemen
{ "books": { "book": "Laskar Pelangi" } }

Ini masalah serius karena client yang mengasumsikan book selalu array akan error saat cuma ada satu item (.map() di JavaScript akan gagal kalau dipanggil di string, bukan array). Solusinya: tool konversi yang baik harus punya opsi "force array" untuk elemen tertentu yang secara semantik memang selalu berupa list, terlepas dari berapa banyak item yang muncul. Bug seperti ini seringkali baru terungkap belakangan, karena test otomatis biasanya kebetulan selalu memakai data contoh dengan lebih dari satu item, sehingga kasus "cuma satu item" luput dari pengujian sampai muncul di production.

Masalah #2: Attribute Perlu Konvensi Penamaan

XML attribute tidak punya padanan langsung di JSON. Konvensi paling umum adalah prefix @ untuk membedakan dari child element:

<!-- XML -->
<book id="42" lang="id">
  <title>Laskar Pelangi</title>
</book>
// JSON dengan konvensi @attr
{
  "book": {
    "@id": "42",
    "@lang": "id",
    "title": "Laskar Pelangi"
  }
}

Konvensi lain yang juga umum: menaruh semua attribute di sub-object terpisah bernama "$" atau "attributes". Yang penting adalah konsisten di seluruh sistem kamu, karena ini bukan standar resmi — beda library, beda konvensi default.

Masalah #3: Mixed Content

Mixed content — teks yang bercampur dengan tag di tengah paragraf — adalah kasus paling sulit dikonversi dengan bersih:

<!-- XML -->
<p>Halo <b>dunia</b>, ini contoh teks.</p>

Tidak ada representasi JSON yang natural untuk ini. Beberapa pendekatan: menyimpan seluruh markup sebagai string HTML mentah di dalam field JSON, atau memecah jadi array of nodes dengan tipe (text/element). Kedua pendekatan sama-sama memerlukan penanganan khusus di sisi consumer, tidak seperti konversi elemen data biasa yang straightforward.

Masalah #4: Text Content Bersama Attribute

Kasus lain yang butuh keputusan desain: elemen yang punya attribute sekaligus text content langsung (bukan child element):

<!-- XML -->
<price currency="IDR">55000</price>
// JSON — text content biasanya ditaruh di key khusus
{
  "price": {
    "@currency": "IDR",
    "#text": "55000"
  }
}

Key #text (atau variasi serupa seperti _text) adalah konvensi umum untuk menampung nilai teks langsung dari elemen yang juga punya attribute.

Contoh Kode: Konversi dengan JavaScript

Untuk kasus sederhana di browser atau Node.js, library seperti fast-xml-parser sering dipakai:

import { XMLParser } from 'fast-xml-parser';

const parser = new XMLParser({
  ignoreAttributes: false,
  attributeNamePrefix: '@',
  isArray: (name) => ['book', 'item'].includes(name)
});

const result = parser.parse(xmlString);
console.log(JSON.stringify(result, null, 2));

Opsi isArray di atas adalah cara mengatasi masalah #1 — kamu bisa secara eksplisit menentukan elemen mana yang harus selalu jadi array, terlepas dari jumlah kemunculannya di XML sumber.

Masalah #5: Namespace XML

XML namespace (xmlns) dipakai untuk menghindari konflik nama tag antar skema berbeda dalam satu dokumen, tapi JSON tidak punya konsep setara. Konversi umum biasanya mempertahankan prefix namespace sebagai bagian dari nama key:

<!-- XML -->
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>...</soap:Body>
</soap:Envelope>
// JSON — prefix dipertahankan sebagai bagian key
{
  "soap:Envelope": {
    "soap:Body": { "...": "..." }
  }
}

Hasil ini valid secara teknis tapi agak canggung dipakai di sisi consumer JavaScript karena key dengan colon perlu diakses lewat bracket notation (obj["soap:Envelope"]), bukan dot notation biasa. Untuk kasus SOAP yang berat namespace, sebagian tim memilih menulis parser/mapper kustom yang membuang informasi namespace sepenuhnya dan hanya mengambil data yang relevan.

Kapan Tidak Perlu Konversi Otomatis?

Untuk struktur XML yang kompleks dengan banyak namespace, mixed content, atau attribute yang bermakna khusus, konversi otomatis generic sering menghasilkan JSON yang "benar secara teknis" tapi aneh dipakai. Dalam kasus ini, kadang lebih baik menulis mapping manual per field yang benar-benar disesuaikan dengan kebutuhan aplikasi, daripada mengandalkan converter generic yang menghasilkan struktur JSON mengikuti bentuk XML apa adanya.

💡 Setelah konversi XML ke JSON, selalu validasi hasilnya untuk memastikan tidak ada masalah format. Gunakan JSONYAMify untuk memformat dan memeriksa JSON hasil konversi sebelum dipakai lebih lanjut.
🔧 Validasi Hasil Konversi JSON di JSONYAMify

How to Convert XML to JSON: A Guide and Pitfalls to Watch For

By Andi Putra Ogie · Updated: July 2026 · 9 min read

Many teams working with legacy XML-based systems (SOAP web services, old data feeds, or enterprise systems) eventually need to convert their data to JSON to be compatible with a modern frontend or a new REST API. Unfortunately, converting XML to JSON isn't as simple as it sounds — because XML and JSON have fundamentally different data models, several design decisions have to be made deliberately, rather than just "auto-converting" and hoping the result is correct.

Why Isn't This Conversion Straightforward?

XML was designed for documents with a flexible structure: elements can have attributes, text mixed with other tags (mixed content), and no built-in array concept. JSON was designed for structured data with clear types: object, array, string, number, boolean, null. This difference in models means there's no single "correct" conversion rule — every conversion tool has to make assumptions, and those assumptions can differ between tools.

Basic Element Mapping Rules

The most basic conversion: an XML element with no attributes and no children becomes a simple key-value string:

<!-- XML -->
<name>Sarah Amelia</name>
// JSON
{ "name": "Sarah Amelia" }

An element with child elements becomes a nested object:

<!-- XML -->
<person>
  <name>Sarah Amelia</name>
  <age>29</age>
</person>
// JSON
{
  "person": {
    "name": "Sarah Amelia",
    "age": "29"
  }
}

Notice age stays a string "29", not a number 29 — since XML has no built-in data types, everything defaults to text. Smarter conversion tools can detect and auto-convert to number/boolean, but this is optional and not every tool does it.

Problem #1: Array vs Single Element

This is the most notorious pitfall in XML-to-JSON conversion. XML has no explicit array concept — repeated elements are just "an element with the same name appearing multiple times":

<!-- XML with 2 items -->
<books>
  <book>Laskar Pelangi</book>
  <book>Bumi Manusia</book>
</books>

<!-- XML with 1 item -->
<books>
  <book>Laskar Pelangi</book>
</books>

A naive conversion will produce an array for the first case, but a single object for the second:

// Case 1 — becomes an array
{ "books": { "book": ["Laskar Pelangi", "Bumi Manusia"] } }

// Case 2 — becomes a single object, NOT a one-element array
{ "books": { "book": "Laskar Pelangi" } }

This is a serious problem because a client that assumes book is always an array will error out when there's only one item (.map() in JavaScript will fail if called on a string instead of an array). The fix: a good conversion tool needs a "force array" option for elements that are semantically always lists, regardless of how many appear in the source XML.

Problem #2: Attributes Need a Naming Convention

XML attributes have no direct equivalent in JSON. The most common convention is an @ prefix to distinguish them from child elements:

<!-- XML -->
<book id="42" lang="id">
  <title>Laskar Pelangi</title>
</book>
// JSON with @attr convention
{
  "book": {
    "@id": "42",
    "@lang": "id",
    "title": "Laskar Pelangi"
  }
}

Another common convention: placing all attributes in a separate sub-object called "$" or "attributes". What matters is being consistent across your system, since this isn't an official standard — different libraries default to different conventions.

Problem #3: Mixed Content

Mixed content — text mixed with tags in the middle of a paragraph — is the hardest case to convert cleanly:

<!-- XML -->
<p>Hello <b>world</b>, this is sample text.</p>

There's no natural JSON representation for this. A few approaches: storing the entire markup as a raw HTML string inside a JSON field, or breaking it into an array of typed nodes (text/element). Both approaches need special handling on the consumer side, unlike ordinary, straightforward data-element conversion.

Problem #4: Text Content Alongside Attributes

Another case that needs a design decision: an element that has both attributes and direct text content (not a child element):

<!-- XML -->
<price currency="IDR">55000</price>
// JSON — text content typically goes in a special key
{
  "price": {
    "@currency": "IDR",
    "#text": "55000"
  }
}

The #text key (or a similar variant like _text) is a common convention for holding the direct text value of an element that also has attributes.

Code Example: Converting With JavaScript

For simple cases in a browser or Node.js, a library like fast-xml-parser is often used:

import { XMLParser } from 'fast-xml-parser';

const parser = new XMLParser({
  ignoreAttributes: false,
  attributeNamePrefix: '@',
  isArray: (name) => ['book', 'item'].includes(name)
});

const result = parser.parse(xmlString);
console.log(JSON.stringify(result, null, 2));

The isArray option above is how you solve problem #1 — you can explicitly specify which elements should always be arrays, regardless of how many times they appear in the source XML.

Problem #5: XML Namespaces

XML namespaces (xmlns) are used to avoid tag name conflicts between different schemas within one document, but JSON has no equivalent concept. A common conversion approach keeps the namespace prefix as part of the key name:

<!-- XML -->
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>...</soap:Body>
</soap:Envelope>
// JSON — prefix kept as part of the key
{
  "soap:Envelope": {
    "soap:Body": { "...": "..." }
  }
}

This result is technically valid but a bit awkward to consume on the JavaScript side, since a key with a colon needs to be accessed via bracket notation (obj["soap:Envelope"]) instead of plain dot notation. For namespace-heavy SOAP cases, some teams choose to write a custom parser/mapper that discards namespace information entirely and only extracts the relevant data.

When Should You Skip Automatic Conversion?

For complex XML structures with lots of namespaces, mixed content, or attributes with special meaning, generic automatic conversion often produces JSON that's "technically correct" but awkward to work with. In those cases, it's sometimes better to write a manual, per-field mapping tailored to the application's actual needs, rather than relying on a generic converter that produces a JSON structure that just mirrors the XML shape as-is.

💡 After converting XML to JSON, always validate the result to make sure there are no formatting issues. Use JSONYAMify to format and inspect the converted JSON before using it further.
🔧 Validate Your Converted JSON on JSONYAMify