Java SAX-Parser Beispiel

Der SAX-Parser in Java bietet eine API zum Parsen von XML-Dokumenten. Der SAX-Parser unterscheidet sich von DOM-Parser, da er das gesamte XML nicht in den Speicher lädt und das XML-Dokument sequentiell liest.

SAX-Parser

javax.xml.parsers.SAXParser bietet Methoden zum Parsen eines XML-Dokuments unter Verwendung von Ereignisbehandlern. Diese Klasse implementiert das XMLReader-Interface und stellt überladene Versionen der parse()-Methoden bereit, um XML-Dokumente aus Datei, InputStream, SAX InputSource und String URI zu lesen. Das eigentliche Parsen wird von der Handler-Klasse durchgeführt. Wir müssen unsere eigene Handler-Klasse erstellen, um das XML-Dokument zu parsen. Wir müssen das org.xml.sax.ContentHandler-Interface implementieren, um unsere eigenen Handler-Klassen zu erstellen. Diese Schnittstelle enthält Rückrufmethoden, die Benachrichtigungen erhalten, wenn ein Ereignis auftritt. Zum Beispiel StartDocument, EndDocument, StartElement, EndElement, CharacterData usw. org.xml.sax.helpers.DefaultHandler bietet eine Standardimplementierung des ContentHandler-Interface, und wir können diese Klasse erweitern, um unseren eigenen Handler zu erstellen. Es ist ratsam, diese Klasse zu erweitern, da wir möglicherweise nur wenige der Methoden implementieren müssen. Durch das Erweitern dieser Klasse bleibt unser Code sauber und wartbar.

Beispiel für einen SAX-Parser

Lassen Sie uns jetzt zum Beispielprogramm für den SAX-Parser springen, ich werde später verschiedene Funktionen im Detail erklären. employees.xml

<?xml version="1.0" encoding="UTF-8"?>
<Employees>
	<Employee id="1">
		<age>29</age>
		<name>Pankaj</name>
		<gender>Male</gender>
		<role>Java Developer</role>
	</Employee>
	<Employee id="2">
		<age>35</age>
		<name>Lisa</name>
		<gender>Female</gender>
		<role>CEO</role>
	</Employee>
	<Employee id="3">
		<age>40</age>
		<name>Tom</name>
		<gender>Male</gender>
		<role>Manager</role>
	</Employee>
	<Employee id="4">
		<age>25</age>
		<name>Meghna</name>
		<gender>Female</gender>
		<role>Manager</role>
	</Employee>
</Employees>

Also, wir haben eine XML-Datei irgendwo im Dateisystem gespeichert, und indem wir sie betrachten, können wir schließen, dass sie eine Liste von Mitarbeitern enthält. Jeder Mitarbeiter hat das Attribut id und die Felder age, name, gender und role. Wir werden den SAX-Parser verwenden, um diese XML zu parsen und eine Liste von Mitarbeiterobjekten zu erstellen. Hier ist das Mitarbeiterobjekt, das das Mitarbeiter-Element aus XML repräsentiert.

package com.journaldev.xml;

public class Employee {
    private int id;
    private String name;
    private String gender;
    private int age;
    private String role;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getRole() {
        return role;
    }
    public void setRole(String role) {
        this.role = role;
    }
    
    @Override
    public String toString() {
        return "Employee:: ID="+this.id+" Name=" + this.name + " Age=" + this.age + " Gender=" + this.gender +
                " Role=" + this.role;
    }
    
}

Lassen Sie uns unsere eigene SAX-Parser-Handlerklasse erstellen, die von der Klasse DefaultHandler erbt.


package com.journaldev.xml.sax;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.journaldev.xml.Employee;

public class MyHandler extends DefaultHandler {

	// Liste zur Aufbewahrung von Mitarbeiterobjekten
	private List empList = null;
	private Employee emp = null;
	private StringBuilder data = null;

	// Getter-Methode für die Mitarbeiterliste
	public List getEmpList() {
		return empList;
	}

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

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

		if (qName.equalsIgnoreCase("Employee")) {
			// Erstellen Sie einen neuen Mitarbeiter und setzen Sie ihn in die Map
			String id = attributes.getValue("id");
			// Initialisieren Sie das Mitarbeiterobjekt und setzen Sie das id-Attribut
			emp = new Employee();
			emp.setId(Integer.parseInt(id));
			// Liste initialisieren
			if (empList == null)
				empList = new ArrayList<>();
		} else if (qName.equalsIgnoreCase("name")) {
			// Boolean-Werte für Felder setzen, die zur Einstellung von Mitarbeitervariablen verwendet werden
			bName = true;
		} else if (qName.equalsIgnoreCase("age")) {
			bAge = true;
		} else if (qName.equalsIgnoreCase("gender")) {
			bGender = true;
		} else if (qName.equalsIgnoreCase("role")) {
			bRole = true;
		}
		// Erstellen Sie den Datenbehälter
		data = new StringBuilder();
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		if (bAge) {
			// Alterelement, setzen Sie das Mitarbeiteralter
			emp.setAge(Integer.parseInt(data.toString()));
			bAge = false;
		} else if (bName) {
			emp.setName(data.toString());
			bName = false;
		} else if (bRole) {
			emp.setRole(data.toString());
			bRole = false;
		} else if (bGender) {
			emp.setGender(data.toString());
			bGender = false;
		}
		
		if (qName.equalsIgnoreCase("Employee")) {
			// Mitarbeiterobjekt zur Liste hinzufügen
			empList.add(emp);
		}
	}

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

MeinHandler enthält die Liste des Mitarbeiter-Objekts als Feld mit einer Getter-Methode nur. Die Mitarbeiter-Objekte werden in den Ereignis-Handlermethoden hinzugefügt. Außerdem haben wir ein Mitarbeiterfeld, das verwendet wird, um ein Mitarbeiterobjekt zu erstellen, und sobald alle Felder gesetzt sind, wird es der Mitarbeiterliste hinzugefügt.

SAX-Parsermethoden zum Überschreiben

Die wichtigen Methoden zum Überschreiben sind startElement(), endElement() und characters(). SAXParser beginnt mit der Analyse des Dokuments. Wenn ein Startelement gefunden wird, wird die Methode startElement() aufgerufen. Wir überschreiben diese Methode, um boolesche Variablen festzulegen, die verwendet werden, um das Element zu identifizieren. Wir verwenden diese Methode auch, um jedes Mal ein neues Employee-Objekt zu erstellen, wenn ein Employee-Startelement gefunden wird. Beachten Sie, wie hier das id-Attribut gelesen wird, um das id-Feld des Employee-Objekts festzulegen. Die Methode characters() wird aufgerufen, wenn Zeichendaten vom SAXParser innerhalb eines Elements gefunden werden. Beachten Sie, dass der SAX-Parser die Daten möglicherweise in mehrere Teile aufteilt und die Methode characters() mehrmals aufruft (lesen Sie die Dokumentation zur Methode characters() der ContentHandler-Klasse). Deshalb verwenden wir einen StringBuilder, um diese Daten mit der append()-Methode zu halten. Das endElement()-Element ist der Ort, an dem wir die StringBuilder-Daten verwenden, um die Eigenschaften des Employee-Objekts festzulegen und das Employee-Objekt zur Liste hinzufügen, sobald wir das Endelement-Tag des Employee gefunden haben. Nachstehend finden Sie das Testprogramm, das MyHandler verwendet, um das obige XML in eine Liste von Employee-Objekten zu analysieren.

package com.journaldev.xml.sax;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import com.journaldev.xml.Employee;

public class XMLParserSAX {

    public static void main(String[] args) {
    SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
    try {
        SAXParser saxParser = saxParserFactory.newSAXParser();
        MyHandler handler = new MyHandler();
        saxParser.parse(new File("/Users/pankaj/employees.xml"), handler);
        //Erhalte Liste der Mitarbeiter
        List empList = handler.getEmpList();
        //Drucke Mitarbeiterinformationen
        for(Employee emp : empList)
            System.out.println(emp);
    } catch (ParserConfigurationException | SAXException | IOException e) {
        e.printStackTrace();
    }
    }

}

Hier ist die Ausgabe des obigen Programms.

Employee:: ID=1 Name=Pankaj Age=29 Gender=Male Role=Java Developer
Employee:: ID=2 Name=Lisa Age=35 Gender=Female Role=CEO
Employee:: ID=3 Name=Tom Age=40 Gender=Male Role=Manager
Employee:: ID=4 Name=Meghna Age=25 Gender=Female Role=Manager

SAXParserFactory bietet Fabrikmethoden, um eine Instanz von SAXParser zu erhalten. Wir übergeben ein File-Objekt an die parse-Methode zusammen mit einer MyHandler-Instanz, um die Rückrufereignisse zu behandeln. SAXParser ist am Anfang ein wenig verwirrend, aber wenn Sie an einem großen XML-Dokument arbeiten, bietet er eine effizientere Möglichkeit, XML zu lesen als der DOM-Parser. Das ist alles für den SAX-Parser in Java.

Sie können das Projekt von unserem GitHub-Repository herunterladen.

Referenz: SAXParser, DefaultHandler

Source:
https://www.digitalocean.com/community/tutorials/java-sax-parser-example