Le parseur SAX en Java offre une API pour analyser les documents XML. Le parseur SAX est différent du parseur DOM car il ne charge pas l’intégralité du XML en mémoire et lit le document XML séquentiellement.
Parseur SAX
javax.xml.parsers.SAXParser
fournit une méthode pour analyser un document XML en utilisant des gestionnaires d’événements. Cette classe implémente l’interface XMLReader
et fournit des versions surchargées des méthodes parse()
pour lire un document XML à partir d’un fichier, d’un InputStream, d’une source d’entrée SAX et d’une URI de chaîne. L’analyse réelle est effectuée par la classe Handler. Nous devons créer notre propre classe de gestionnaire pour analyser le document XML. Nous devons implémenter l’interface org.xml.sax.ContentHandler
pour créer nos propres classes de gestionnaire. Cette interface contient des méthodes de rappel qui reçoivent une notification lorsqu’un événement se produit. Par exemple, StartDocument, EndDocument, StartElement, EndElement, CharacterData, etc. org.xml.sax.helpers.DefaultHandler
fournit une implémentation par défaut de l’interface ContentHandler et nous pouvons étendre cette classe pour créer notre propre gestionnaire. Il est conseillé d’étendre cette classe car nous pourrions avoir besoin que de quelques-unes des méthodes à implémenter. Étendre cette classe permettra de garder notre code plus propre et maintenable.
Exemple de parseur SAX
Passons maintenant à l’exemple de programme de parseur SAX, je vais expliquer différentes fonctionnalités en détail plus tard. 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>
Donc, nous avons un fichier XML stocké quelque part dans le système de fichiers et en le regardant, nous pouvons conclure qu’il contient une liste d’employés. Chaque employé a l’attribut id
et les champs age
, name
, gender
et role
. Nous utiliserons un analyseur SAX pour analyser ce XML et créer une liste d’objets Employee. Voici l’objet Employee représentant l’élément Employee du XML.
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;
}
}
Créons notre propre classe de gestionnaire SAX en étendant la classe DefaultHandler.
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 pour contenir des objets Employee
private List empList = null;
private Employee emp = null;
private StringBuilder data = null;
// Méthode getter pour la liste des employés
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")) {
// Créez un nouvel employé et placez-le dans la carte
String id = attributes.getValue("id");
// Initialisez l'objet Employee et définissez l'attribut id
emp = new Employee();
emp.setId(Integer.parseInt(id));
// Initialisez la liste
if (empList == null)
empList = new ArrayList<>();
} else if (qName.equalsIgnoreCase("name")) {
// Définissez des valeurs booléennes pour les champs, qui seront utilisées pour définir les variables Employee
bName = true;
} else if (qName.equalsIgnoreCase("age")) {
bAge = true;
} else if (qName.equalsIgnoreCase("gender")) {
bGender = true;
} else if (qName.equalsIgnoreCase("role")) {
bRole = true;
}
// Créez le conteneur de données
data = new StringBuilder();
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (bAge) {
// élément age, définissez l'âge de l'employé
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")) {
// Ajoutez l'objet Employee à la liste
empList.add(emp);
}
}
@Override
public void characters(char ch[], int start, int length) throws SAXException {
data.append(new String(ch, start, length));
}
}
MyHandler contient la liste de l’objet Employee
en tant que champ avec une méthode getter uniquement. Les objets Employee
sont ajoutés dans les méthodes de gestionnaire d’événements. De plus, nous avons un champ Employee qui sera utilisé pour créer un objet Employee et une fois que tous les champs sont définis, l’ajouter à la liste des employés.
Méthodes à remplacer du parseur SAX
Les méthodes importantes à remplacer sont startElement()
, endElement()
et characters()
. SAXParser
commence l’analyse du document lorsqu’un élément de début est trouvé, la méthode startElement()
est appelée. Nous remplaçons cette méthode pour définir des variables booléennes qui seront utilisées pour identifier l’élément. Nous utilisons également cette méthode pour créer un nouvel objet Employee chaque fois qu’un élément de début d’Employee est trouvé. Vérifiez comment l’attribut id est lu ici pour définir le champ id
de l’objet Employee. La méthode characters()
est appelée lorsque des données de caractères sont trouvées par SAXParser à l’intérieur d’un élément. Notez que le parseur SAX peut diviser les données en plusieurs morceaux et appeler la méthode characters()
plusieurs fois (lisez la documentation de la méthode characters() de la classe ContentHandler). C’est pourquoi nous utilisons StringBuilder pour conserver ces données en utilisant la méthode append(). La méthode endElement()
est l’endroit où nous utilisons les données de StringBuilder pour définir les propriétés de l’objet employee et ajouter l’objet Employee à la liste chaque fois que nous trouvons la balise de fin d’Employee. Voici le programme de test qui utilise MyHandler
pour analyser le XML ci-dessus en liste d’objets Employee.
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);
//Obtenir la liste des employés
List empList = handler.getEmpList();
//afficher les informations sur l'employé
for(Employee emp : empList)
System.out.println(emp);
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
}
Voici la sortie du programme ci-dessus.
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
fournit des méthodes de fabrique pour obtenir l’instance de SAXParser
. Nous passons un objet File à la méthode parse ainsi qu’une instance de MyHandler pour gérer les événements de rappel. SAXParser est un peu déroutant au début, mais si vous travaillez sur un grand document XML, il offre un moyen plus efficace de le lire que DOM Parser. C’est tout pour SAX Parser en Java.
Vous pouvez télécharger le projet depuis notre référentiel GitHub .
Référence : SAXParser , DefaultHandler
Source:
https://www.digitalocean.com/community/tutorials/java-sax-parser-example