Analyse d'un fichier XML à l'aide de SAX Parser

1. Vue d'ensemble

SAX, également connu sous le nom d' API simple pour XML , est utilisé pour analyser les documents XML.

Dans ce tutoriel, nous allons apprendre ce qu'est SAX et pourquoi, quand et comment il doit être utilisé.

2. SAX : l'API simple pour XML

SAX est une API utilisée pour analyser les documents XML. Il est basé sur les événements générés lors de la lecture du document. Les méthodes de rappel reçoivent ces événements. Un gestionnaire personnalisé contient ces méthodes de rappel.

L'API est efficace car elle supprime les événements juste après que les rappels les ont reçus. Par conséquent, SAX a une gestion de mémoire efficace , contrairement à DOM, par exemple.

3. SAX contre DOM

DOM signifie Document Object Model. L' analyseur DOM ne repose pas sur les événements . De plus, il charge tout le document XML en mémoire pour l'analyser. SAX est plus efficace en mémoire que DOM.

DOM a aussi ses avantages. Par exemple, DOM prend en charge XPath. Cela facilite également l'utilisation de l'ensemble de l'arborescence des documents à la fois puisque le document est chargé en mémoire .

4. SAX contre StAX

StAX est plus récent que SAX et DOM. Il signifie Streaming API for XML .

La principale différence avec SAX est que StAX utilise un mécanisme de traction au lieu du mécanisme de poussée de SAX (utilisant des rappels).

Cela signifie que le contrôle est donné au client pour décider quand les événements doivent être extraits. Par conséquent, il n'y a aucune obligation de retirer tout le document si une partie seulement est nécessaire.

Il fournit une API simple pour travailler avec XML avec une méthode d'analyse efficace de la mémoire.

Contrairement à SAX, il ne fournit pas de validation de schéma comme l'une de ses fonctionnalités.

5. Analyse du fichier XML à l'aide d'un gestionnaire personnalisé

Utilisons maintenant le XML suivant représentant le site Web de Baeldung et ses articles:

   Parsing an XML File Using SAX Parser SAX Parser's Lorem ipsum...   Parsing an XML File Using DOM Parser DOM Parser's Lorem ipsum...   Parsing an XML File Using StAX Parser StAX's Lorem ipsum...   

Nous commencerons par créer des POJO pour notre élément racine Baeldung et ses enfants:

public class Baeldung { private List articleList; // usual getters and setters } 
public class BaeldungArticle { private String title; private String content; // usual getters and setters } 

Nous continuerons en créant le BaeldungHandler . Cette classe implémentera les méthodes de rappel nécessaires pour capturer les événements.

Nous remplacerons quatre méthodes de la superclasse DefaultHandler, chacune caractérisant un événement:

    • caractères (char [], int, int) reçoit des caractères avec des limites. Nous allons les convertir en String et le stocker dans une variable de BaeldungHandler
    • startDocument () est appelé lorsque l'analyse commence - nous l'utiliserons pour construire notre instance Baeldung
    • startElement () est invoqué lorsque l'analyse commence pour un élément - nous l'utilisons pour construire des instances List ou BaeldungArticle - qName nous aide à faire la distinction entre les deux types
    • endElement () est invoqué lorsque l'analyse se termine pour un élément - c'est à ce moment que nous attribuerons le contenu des balises à leurs variables respectives

Avec tous les callbacks définis, nous pouvons maintenant écrire la classe BaeldungHandler :

public class BaeldungHandler extends DefaultHandler { private static final String ARTICLES = "articles"; private static final String ARTICLE = "article"; private static final String TITLE = "title"; private static final String CONTENT = "content"; private Baeldung website; private String elementValue; @Override public void characters(char[] ch, int start, int length) throws SAXException { elementValue = new String(ch, start, length); } @Override public void startDocument() throws SAXException { website = new Baeldung(); } @Override public void startElement(String uri, String lName, String qName, Attributes attr) throws SAXException { switch (qName) { case ARTICLES: website.articleList = new ArrayList(); break; case ARTICLE: website.articleList.add(new BaeldungArticle()); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { switch (qName) { case TITLE: latestArticle().title = elementValue; break; case CONTENT: latestArticle().content = elementValue; break; } } private BaeldungArticle latestArticle() { List articleList = website.articleList; int latestArticleIndex = articleList.size() - 1; return articleList.get(latestArticleIndex); } public Baeldung getWebsite() { return website; } } 

Des constantes de chaîne ont également été ajoutées pour augmenter la lisibilité. Une méthode pour récupérer le dernier article rencontré est également pratique. Enfin, nous avons besoin d'un getter pour l' objet Baeldung .

Notez que ce qui précède n'est pas thread-safe car nous conservons l'état entre les appels de méthode.

6. Test de l'analyseur

Afin de tester l'analyseur, nous allons instancier le SaxFactory , le SaxParser et aussi le BaeldungHandler :

SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); SaxParserMain.BaeldungHandler baeldungHandler = new SaxParserMain.BaeldungHandler(); 

Après cela, nous analyserons le fichier XML et affirmerons que l'objet contient tous les éléments attendus analysés:

saxParser.parse("src/test/resources/sax/baeldung.xml", baeldungHandler); SaxParserMain.Baeldung result = baeldungHandler.getWebsite(); assertNotNull(result); List articles = result.getArticleList(); assertNotNull(articles); assertEquals(3, articles.size()); SaxParserMain.BaeldungArticle articleOne = articles.get(0); assertEquals("Parsing an XML File Using SAX Parser", articleOne.getTitle()); assertEquals("SAX Parser's Lorem ipsum...", articleOne.getContent()); SaxParserMain.BaeldungArticle articleTwo = articles.get(1); assertEquals("Parsing an XML File Using DOM Parser", articleTwo.getTitle()); assertEquals("DOM Parser's Lorem ipsum...", articleTwo.getContent()); SaxParserMain.BaeldungArticle articleThree = articles.get(2); assertEquals("Parsing an XML File Using StAX Parser", articleThree.getTitle()); assertEquals("StAX Parser's Lorem ipsum...", articleThree.getContent()); 

Comme prévu, le baeldung a été correctement analysé et contient les sous-objets attendus.

7. Conclusion

Nous venons de découvrir comment utiliser SAX pour analyser des fichiers XML. C'est une API puissante générant une faible empreinte mémoire dans nos applications.

Comme d'habitude, le code de cet article est disponible à l'adresse over sur GitHub.