Skip to main content

🧩 Java SAX Parser Örneği: Büyük XML Dosyalarını Verimli Ayrıştırma

Meta Açıklaması (155 karakter):
Java'da SAX ayrıştırıcısını kullanarak olay güdümlü (event-driven) bir yaklaşımla XML belgelerini bellek dostu şekilde nasıl işleyebileceğinizi öğrenin.


🧠 Bu Rehberde Ne Öğreneceksiniz?

Bu rehberde, Java SAX Parser (Simple API for XML) kullanarak XML belgelerini nasıl okuyabileceğinizi öğreneceksiniz.
DOM Parser’dan farklı olarak SAX, XML dosyasını tamamını belleğe yüklemeden, satır satır (sıralı) olarak işler.
Böylece özellikle büyük XML dosyaları üzerinde çalışırken yüksek performans sağlar.

Ayrıca kendi özel handler sınıfınızı (DefaultHandler) oluşturarak XML olaylarını (startElement, endElement, characters) yönetmeyi öğreneceksiniz.


🔍 1. SAX Parser Nedir?

SAX Parser, XML belgelerini olay tabanlı olarak okuyan bir Java API’sidir.
javax.xml.parsers.SAXParser sınıfı, XML’i tararken belirli olaylarda (örneğin bir etiketin başlangıcı veya sonu) metot çağrıları yapar.

Temel Özellikleri:

  • Bellek dostu: XML’i parça parça işler, tamamını belleğe almaz.
  • Event-driven: Etiket başı/sonu ve içerik olaylarıyla çalışır.
  • Büyük dosyalarda idealdir: GB boyutlu XML belgeleri için tercih edilir.
  • Okuma odaklıdır: SAX yalnızca XML’i okur, yazma işlemi yapmaz.

💡 Karşılaştırma: DOM, XML’i ağaç yapısına yüklerken; SAX akış (stream) bazlı çalışır.


⚙️ 2. SAX Parser’ın Çalışma Mantığı

Ayrıştırma işlemi sırasında SAX Parser aşağıdaki olaylar için metotları tetikler:

🧠 Olay🧾 Metot🔍 Açıklama
Belge BaşlangıcıstartDocument()XML okuma başladığında çağrılır.
Belge SonuendDocument()Okuma tamamlandığında tetiklenir.
Etiket BaşlangıcıstartElement()Yeni bir XML etiketi bulunduğunda çağrılır.
Etiket SonuendElement()Etiket kapanırken çağrılır.
Metin Verisicharacters()Etiket içindeki veri işlendiğinde çağrılır.

📘 Kullanım:
org.xml.sax.helpers.DefaultHandler sınıfını genişleterek yalnızca gerekli metotları override edebiliriz.
Bu, kodu daha sade ve bakımı kolay hale getirir.


📄 3. Örnek XML Belgesi

Aşağıdaki örnek XML, çalışanları temsil eder ve her birinin id, age, name, gender, role alanlarını içerir.

<?xml version="1.0" encoding="UTF-8"?>
<Employees>
<Employee id="1">
<age>29</age>
<name>Rabisu</name>
<gender>Male</gender>
<role>Cloud Architect</role>
</Employee>
<Employee id="2">
<age>35</age>
<name>Lisa</name>
<gender>Female</gender>
<role>CEO</role>
</Employee>
</Employees>

🧱 4. Employee Sınıfı

XML’deki <Employee> etiketini temsil eden Java sınıfı:


package com.rabisu.xml;

public class Employee {
private int id;
private String name;
private String gender;
private int age;
private String role;

// Getter ve Setter metotları

@Override
public String toString() {
return "Personel:: ID=" + this.id + " İsim=" + this.name +
" Yaş=" + this.age + " Cinsiyet=" + this.gender +
" Rol=" + this.role;
}
}

📘 Açıklama: Bu sınıf, XML’den alınan verilerin nesne tabanlı tutulmasını sağlar.


🧩 5. Özel İşleyici Sınıfı (MyHandler)

Handler sınıfı, XML okuma olaylarını yakalayıp Employee nesnelerine dönüştürür.


package com.rabisu.xml.sax;

import java.util.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import com.rabisu.xml.Employee;

public class MyHandler extends DefaultHandler {
private List<Employee> empList = null;
private Employee emp = null;
private StringBuilder data = null;

boolean bAge = false, bName = false, bGender = false, bRole = false;

public List<Employee> getEmpList() {
return empList;
}

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("Employee")) {
String id = attributes.getValue("id");
emp = new Employee();
emp.setId(Integer.parseInt(id));
if (empList == null) empList = new ArrayList<>();
} else if (qName.equalsIgnoreCase("name")) {
bName = true;
} else if (qName.equalsIgnoreCase("age")) {
bAge = true;
} else if (qName.equalsIgnoreCase("gender")) {
bGender = true;
} else if (qName.equalsIgnoreCase("role")) {
bRole = true;
}
data = new StringBuilder();
}

@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (bAge) { emp.setAge(Integer.parseInt(data.toString())); bAge = false; }
else if (bName) { emp.setName(data.toString()); bName = false; }
else if (bGender) { emp.setGender(data.toString()); bGender = false; }
else if (bRole) { emp.setRole(data.toString()); bRole = false; }

if (qName.equalsIgnoreCase("Employee")) empList.add(emp);
}

@Override
public void characters(char ch[], int start, int length) throws SAXException {
data.append(new String(ch, start, length));
}
}

💬 Neden StringBuilder kullanılır? SAX, bir etiketin içindeki veriyi bazen parçalara böler. Bu yüzden characters() metodu birden fazla çağrılabilir; StringBuilder bu parçaları birleştirir.


⚡ 6. Ayrıştırmayı Başlatmak


package com.rabisu.xml.sax;

import java.io.File;
import java.util.List;
import javax.xml.parsers.*;

import com.rabisu.xml.Employee;

public class XMLParserSAX {
public static void main(String[] args) {
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = factory.newSAXParser();
MyHandler handler = new MyHandler();
saxParser.parse(new File("/usr/local/data/personel_kayit.xml"), handler);

List<Employee> empList = handler.getEmpList();
for (Employee emp : empList)
System.out.println(emp);
} catch (Exception e) {
e.printStackTrace();
}
}
}

📘 Açıklama: Bu kod, XML dosyasını okur ve her <Employee> elemanını Employee nesnesine dönüştürür.


📤 7. Örnek Çıktı


Personel:: ID=1 İsim=Rabisu Yaş=29 Cinsiyet=Male Rol=Cloud Architect
Personel:: ID=2 İsim=Lisa Yaş=35 Cinsiyet=Female Rol=CEO

💡 8. Dikkat Edilmesi Gereken Noktalar

💡 Durum🧾 Açıklama
Bellek VerimliliğiSAX, XML’i parça parça okuyarak RAM kullanımını düşürür.
Tek Yönlü OkumaVeri yalnızca ileri yönde okunur, geri dönüş yapılamaz.
Event TabanlıEtiket başlangıcı ve bitişinde olaylar tetiklenir.
DefaultHandler KullanımıYalnızca gerekli metotları override ederek sade kod yazılır.
DOM AlternatifiKüçük XML dosyalarında DOM tercih edilebilir.

❓ Sıkça Sorulan Sorular (SSS)

  1. SAX ve DOM arasındaki fark nedir?

DOM tüm XML’i belleğe yükler, SAX ise satır satır işler. SAX büyük dosyalarda çok daha hafiftir.

  1. SAX XML’i düzenleyebilir mi?

Hayır. SAX yalnızca okuma (read-only) işlemi yapar. Düzenleme için DOM veya StAX kullanılmalıdır.

  1. characters() neden birden fazla çağrılır?

SAX parser metni parçalara ayırabilir, bu yüzden tüm parçaları StringBuilder ile birleştiririz.

  1. Hangi durumlarda SAX kullanmalıyım?

Büyük XML dosyalarıyla çalışıyorsanız veya bellek sınırlıysa SAX idealdir.

  1. startElement’teki boolean değişkenler ne işe yarar?

Bu değişkenler, characters() çağrısı sırasında hangi XML alanının okunduğunu belirler.


🏁 Sonuç

SAX Parser, Java’da büyük XML verilerini minimum bellek kullanımıyla ayrıştırmanın en verimli yollarından biridir. Olay tabanlı yapısı sayesinde veri akışını kontrol altında tutar ve performansı artırır.

💬 Deneyin: Rabisu Bulut platformunda kuracağınız yüksek performanslı bir Java çalışma ortamı ile SAX Parser’ın verimliliğini hemen test edebilirsiniz. 🚀