Java SAX Parser Beispiel

javax.xml.parsers.SAXParser bietet eine Methode, um XML-Dokumente mithilfe von Ereignishandlern zu parsen. Diese Klasse implementiert das XMLReader-Interface und bietet überladene Versionen der Parse()-Methoden, um XML-Dokumente aus Dateien, InputStreams, SAX InputSource und String URI zu lesen. Das eigentliche Parsing 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 Interface org.xml.sax.ContentHandler implementieren, um unsere eigenen Handler-Klassen zu erstellen. Dieses Interface enthält Callback-Methoden, die Benachrichtigungen erhalten, wenn ein Ereignis eintritt. Zum Beispiel StartDocument, EndDocument, StartElement, EndElement, CharacterData usw. org.xml.sax.helpers.DefaultHandler bietet eine Standardimplementierung des ContentHandler-Interfaces, 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 einige der Methoden implementieren müssen. Das Erweitern dieser Klasse wird unseren Code sauberer und wartbarer machen.

Lassen Sie uns jetzt zum SAX-Parser-Beispielprogramm springen, ich werde die verschiedenen Funktionen später im Detail erklären.

employees.xml – Java SAX Parser

<?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>

Wir haben also eine XML-Datei, die irgendwo im Dateisystem gespeichert ist, und wenn wir sie betrachten, können wir schlussfolgern, dass sie eine Liste von Mitarbeitern enthält. Jeder Mitarbeiter hat ein ID-Attribut und Felder für Alter, Name, Geschlecht und Rolle. Wir werden den SAX-Parser verwenden, um dieses XML zu parsen und eine Liste von Employee-Objekten zu erstellen.

Hier ist das Employee-Objekt, das das Employee-Element aus dem XML darstellt.

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 die DefaultHandler-Klasse erweitert.

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 {

    // List to hold Employees object
    private List<Employee> empList = null;
    private Employee emp = = null;
    private StringBuilder data = null;

    // getter method for employee list
    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")) {
            // create a new Employee and put it in Map
            String id = attributes.getValue("id");
            // initialize Employee object and set id attribute
            emp = new Employee();
            emp.setId(Integer.parseInt(id));
            // initialize list
            if (empList == null)
                empList = new ArrayList<>();
        } else if (qName.equalsIgnoreCase("name")) {
            // set boolean values for fields, will be used in setting Employee variables
            bName = true;
        } else if (qName.equalsIgnoreCase("age")) {
            bAge = true;
        } else if (qName.equalsIgnoreCase("gender")) {
            bGender = true;
        } else if (qName.equalsIgnoreCase("role")) {
            bRole = true;
        }
        // create the data container
        data = new StringBuilder();
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (bAge) {
            // age element, set Employee age
            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")) {
            // add Employee object to list
            empList.add(emp);
        }
    }

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

MyHandler enthält die Liste der Employee-Objekte als Feld mit nur einer Getter-Methode. Die Employee-Objekte werden in den Ereignishandlermethoden hinzugefügt. Außerdem haben wir ein Employee-Feld, das verwendet wird, um ein Employee-Objekt zu erstellen, und sobald alle Felder gesetzt sind, fügen wir es der Mitarbeiterliste hinzu.

Zu überschreibende Java SAX Parser Methoden

Die wichtigen Methoden, die überschrieben werden müssen, sind startElement(), endElement() und characters(). Wenn das SAXParser ein Startelement findet, wird die Methode startElement() aufgerufen. Wir überschreiben diese Methode, um Boolesche Variablen zu setzen, die verwendet werden, um das Element zu identifizieren. Wir verwenden diese Methode auch, um ein neues Employee-Objekt zu erstellen, jedes Mal wenn ein Employee-Startelement gefunden wird. Schauen Sie, wie das ID-Attribut hier gelesen wird, um das Feld ID des Employee-Objekts zu setzen. Die Methode characters() wird aufgerufen, wenn der SAXParser Zeichendaten innerhalb eines Elements findet. Beachten Sie, dass der SAX-Parser die Daten in mehrere Teile unterteilen und die Methode characters() mehrmals aufrufen kann (lesen Sie die Dokumentation der Methode characters() der ContentHandler-Klasse). Deshalb verwenden wir StringBuilder, um diese Daten mit der Methode append() zu speichern. Die Methode endElement() ist der Ort, an dem wir die StringBuilder-Daten verwenden, um die Eigenschaften des Employee-Objekts zu setzen und das Employee-Objekt zur Liste hinzuzufügen, wann immer wir ein Employee-Endelement-Tag finden.

Unten ist das Testprogramm, das MyHandler verwendet, um das obige XML in eine Liste von Employee-Objekten zu parsen.

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);
            //Get Employees list
            List empList = handler.getEmpList();
            //print employee information
            for(Employee emp : empList)
                System.out.println(emp);
        } catch (ParserConfigurationException | SAXException | IOException e) {
            e.printStackTrace();
        }
    }

}

Hier ist der Output 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 die SAXParser-Instanz zu erhalten. Wir übergeben ein File-Objekt an die Parse-Methode zusammen mit der MyHandler-Instanz, um die Callback-Ereignisse zu behandeln. SAXParser ist anfangs vielleicht ein wenig verwirrend, aber wenn Sie mit einem großen XML-Dokument arbeiten, bietet es eine effizientere Methode zum Lesen von XML als der DOM-Parser. Das ist alles zum SAX-Parser in Java.

Kostenlosen Account erstellen

Registrieren Sie sich jetzt und erhalten Sie Zugang zu unseren Cloud Produkten.

Das könnte Sie auch interessieren: