XML lebih tua dari JSON tetapi tetap menghidupi sistem besar: interface antar-bank berbasis SOAP, berkas konfigurasi aplikasi, feed RSS, hingga export dari sistem enterprise. Bedanya dengan JSON: XML adalah dokumen bertingkat yang ketat — deklarasi versi wajib, setiap tag harus tertutup, dan data bisa hidup sebagai teks elemen maupun atribut. Chapter ini membahas cara menulis dan membaca dokumen tersebut:

  • Struktur pohon XML: elemen, atribut, dan teks
  • Menulis berkas XML dengan fprintf (portabel) dan xmlwrite (MATLAB)
  • Membaca menjadi struct dengan readstruct (MATLAB R2020b+)
  • Menelusuri pohon DOM hasil xmlread (MATLAB)

Struktur Dokumen XML #

Aturannya: satu dokumen XML memiliki tepat satu elemen root yang membungkus seluruh isi; di dalamnya, elemen boleh bersarang, membawa atribut, dan memuat teks. Dokumen contoh kita sepanjang chapter — katalog dua buku — berbentuk berikut:

xml
<?xml version="1.0" encoding="UTF-8"?>
<katalog>
  <buku kategori="teknik">
    <judul>Belajar MATLAB</judul>
    <harga>150000</harga>
  </buku>
  <buku kategori="bisnis">
    <judul>Analisis Data UMKM</judul>
    <harga>95000</harga>
  </buku>
</katalog>

Mari kita petakan pohonnya:

Diagram tersebut memperlihatkan tiga jenis penghuni XML: elemen (katalog, buku, judul, harga), atribut (kategori="teknik" menempel pada elemen buku), dan teks (Belajar MATLAB hidup di dalam elemen judul). Mekanismenya di sisi pembaca: parser XML membaca seluruh dokumen dan membangun Document Object Model (DOM) — pohon objek di memori yang meniru struktur berkas — sehingga program bisa melompat ke elemen mana pun lewat nama tag.

Karena XML pada akhirnya adalah teks, penulisan paling portabel memakai infrastruktur fopen + fprintf yang sudah kita kuasai. Mekanismenya: skrip menulis deklarasi dan elemen berurutan — tag pembuka, isi, tag penutup — dengan indentasi dua spasi agar berkas mudah dibaca manusia:

matlab
fid = fopen('katalog.xml', 'w');
fprintf(fid, '<?xml version="1.0" encoding="UTF-8"?>\n');
fprintf(fid, '<katalog>\n');
fprintf(fid, '  <buku kategori="teknik">\n');
fprintf(fid, '    <judul>Belajar MATLAB</judul>\n');
fprintf(fid, '    <harga>150000</harga>\n');
fprintf(fid, '  </buku>\n');
fprintf(fid, '  <buku kategori="bisnis">\n');
fprintf(fid, '    <judul>Analisis Data UMKM</judul>\n');
fprintf(fid, '    <harga>95000</harga>\n');
fprintf(fid, '  </buku>\n');
fprintf(fid, '</katalog>\n');
fclose(fid);
fprintf('katalog.xml tertulis: %d\n', exist('katalog.xml', 'file'));

Output yang Dihasilkan:

text
katalog.xml tertulis: 2

Mari kita bedah baris-baris kode di atas:

  1. Baris 2 (deklarasi XML): baris <?xml ...?> bukan elemen melainkan deklarasi wajib di dokumen resmi — versi dan encoding dinyatakan di sini.
  2. Baris 3 dan 13 (<katalog> … </katalog>): elemen root dibuka paling awal dan ditutup paling akhir — semua elemen lain hidup di antaranya.
  3. Baris 4-8 (blok buku pertama): atribut kategori="teknik" ditulis di dalam tag pembuka; elemen anak judul dan harga menjorok dua spasi demi keterbacaan.
  4. Baris 14 (fclose): penutupan berkas memastikan seluruh tag benar-benar sampai ke disk.

Verifikasi Ringkas dengan fgetl dan strfind #

Sebelum memakai parser berat, verifikasi ringkas bisa dilakukan dengan alat teks biasa. Mekanismenya: fgetl membaca baris demi baris, strfind mendeteksi tag yang dicari, dan sscanf menarik angka dari baris harga:

matlab
fid = fopen('katalog.xml', 'r');
nBuku = 0;
totalHarga = 0;
while true
  baris = fgetl(fid);
  if ~ischar(baris), break; end
  if ~isempty(strfind(baris, '<buku '))    % tag pembuka ber-atribut
    nBuku = nBuku + 1;
  end
  if ~isempty(strfind(baris, '<harga>'))   % tag harga berisi angka
    totalHarga = totalHarga + sscanf(strtrim(baris), '<harga>%d</harga>');
  end
end
fclose(fid);
fprintf('jumlah elemen buku : %d\n', nBuku);
fprintf('total harga        : Rp%d\n', totalHarga);

Output yang Dihasilkan:

text
jumlah elemen buku : 2
total harga        : Rp245000

Mari kita bedah baris-baris kode di atas:

  1. Baris 8 (strfind(baris, '<buku ')): spasi di ujung pola memastikan yang cocok adalah tag pembuka <buku kategori=...>, bukan tag penutup </buku>.
  2. Baris 12 (sscanf(strtrim(baris), '<harga>%d</harga>')): strtrim membuang indentasi supaya format literal '<harga>%d</harga>' cocok persis dengan barisnya; %d menangkap angka 150000 dan 95000.
  3. Baris 16-17 (fprintf): hasil verifikasi — dua elemen buku dan total harga Rp245.000 — tercetak deterministik.

readstruct: XML ke Struct (MATLAB R2020b+) #

Untuk pembacaan sesungguhnya, MATLAB R2020b menyediakan readstruct yang membangun struct array dari dokumen XML atau JSON dalam satu panggilan. Mekanismenya: elemen berulang menjadi elemen struct array, elemen anak menjadi field, dan atribut juga menjadi field:

matlab
S = readstruct("katalog.xml");
fprintf('jumlah buku: %d\n', numel(S.buku));
fprintf('buku pertama: %s\n', S.buku(1).judul);

Output yang Dihasilkan (tampilan S di Command Window MATLAB):

text
S = 
  struct with fields:

    buku: [2×1 struct]

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (readstruct("katalog.xml")): ekstensi .xml membuat readstruct mem-parse XML; atribut kategori ikut menjadi field, sehingga S.buku(1).kategori bernilai "teknik".
  2. Baris 2-3 (numel(S.buku)): dua elemen <buku> menjadi struct array 2×1 — elemen XML berulang dan elemen struct array saling mewakili.
  3. Tampilan S: MATLAB menampilkan field buku sebagai [2×1 struct]; teks isi elemen dibaca sebagai string ("Belajar MATLAB").

xmlread dan Penelusuran DOM #

Kendali penuh atas pohon dokumen diberikan oleh xmlread, yang mengembalikan objek DOM siap ditelusuri. Mekanismenya: DOMnode.getDocumentElement memberi elemen root, getElementsByTagName('buku') mengumpulkan seluruh elemen bertag buku, dan item(k) mengambil elemen ke-k (indeks mulai 0). Metode-metode ini berasal dari pustaka Java (Apache Xerces) yang dibungkus MATLAB:

matlab
DOMnode = xmlread('katalog.xml');
katalogNode = DOMnode.getDocumentElement;            % elemen root <katalog>
bukuList = katalogNode.getElementsByTagName('buku'); % semua elemen <buku>
for k = 0:bukuList.getLength - 1
  node = bukuList.item(k);
  kategori = char(node.getAttribute('kategori'));    % atribut elemen
  judulNode = node.getElementsByTagName('judul').item(0);
  judul = char(judulNode.getFirstChild.getData);     % teks di dalam elemen
  fprintf('buku: %s (%s)\n', judul, kategori);
end

Penjelasan sintaksisnya: loop berjalan dari 0 sampai getLength - 1 karena DOM mengindeks dari nol. node.getAttribute('kategori') membaca atribut langsung dari elemen; teks Belajar MATLAB diambil dua langkah — getFirstChild menuju text node di dalam <judul>, lalu getData mengambil isinya — dan char(...) mengubah objek Java menjadi char MATLAB agar bisa dicetak. Loop tersebut menghasilkan dua baris: buku: Belajar MATLAB (teknik) dan buku: Analisis Data UMKM (bisnis).

Untuk arah sebaliknya, xmlwrite(DOMnode, 'hasil.xml') menulis objek DOM kembali menjadi berkas — modifikasi pohon di memori lalu simpan. Kebutuhan query yang lebih selektif dilayani XPath sejak R2021a melalui kelas matlab.io.xml.xpath.Evaluator: evaluator mengevaluasi ekspresi seperti "//buku[@kategori='teknik']/judul" langsung terhadap berkas dan mengembalikan node yang cocok — satu baris pengganti penelusuran manual di atas.

Berkas contoh.m pada bagian bawah halaman menguji jalur portabel secara utuh — menulis katalog.xml dengan fprintf, memverifikasi isinya dengan fgetl + strfind + sscanf, lalu menghapus berkas demo — sedangkan jalur readstruct/xmlread berjalan di MATLAB sesuai sintaks yang telah dibedah.

Ringkasan #

XML dibaca dengan dua gaya di MATLAB: readstruct (R2020b+) mengubah pohon elemen menjadi struct array — atribut ikut menjadi field — sementara xmlread memberi akses DOM penuh lewat getDocumentElement, getElementsByTagName, dan item. Penulisan paling portabel tetap fprintf karena XML hakikatnya teks; xmlwrite menuliskan DOM hasil editan, dan XPath (R2021a+) memilih node tanpa penelusuran manual. Data tidak selalu berbentuk teks yang bisa dibaca mata — gambar, audio, format biner khusus — MATLAB membacanya per byte, dan itu pembahasan chapter Membaca File Biner.