🧩 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 Sonu | endDocument() | Okuma tamamlandığında tetiklenir. |
| Etiket Başlangıcı | startElement() | Yeni bir XML etiketi bulunduğunda çağrılır. |
| Etiket Sonu | endElement() | Etiket kapanırken çağrılır. |
| Metin Verisi | characters() | 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ği | SAX, XML’i parça parça okuyarak RAM kullanımını düşürür. |
| Tek Yönlü Okuma | Veri 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 Alternatifi | Küçük XML dosyalarında DOM tercih edilebilir. |
❓ Sıkça Sorulan Sorular (SSS)
- 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.
- 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.
- 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.
- Hangi durumlarda SAX kullanmalıyım?
Büyük XML dosyalarıyla çalışıyorsanız veya bellek sınırlıysa SAX idealdir.
- 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. 🚀