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