Java Language Analyse d'un document à l'aide de l'API StAX


Exemple

Considérant le document suivant:

<?xml version='1.0' encoding='UTF-8' ?>
<library>
   <book id='1'>Effective Java</book>
   <book id='2'>Java Concurrency In Practice</book>
   <notABook id='3'>This is not a book element</notABook>
</library>

On peut utiliser le code suivant pour l'analyser et créer une carte des titres de livres par identifiant de livre.

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

public class StaxDemo {

public static void main(String[] args) throws Exception {
    String xmlDocument = "<?xml version='1.0' encoding='UTF-8' ?>"
            + "<library>"
                + "<book id='1'>Effective Java</book>"
                + "<book id='2'>Java Concurrency In Practice</book>"
                + "<notABook id='3'>This is not a book element </notABook>"
            + "</library>";

    XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
    // Various flavors are possible, e.g. from an InputStream, a Source, ...
    XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new StringReader(xmlDocument));

    Map<Integer, String> bookTitlesById = new HashMap<>();

    // We go through each event using a loop
    while (xmlStreamReader.hasNext()) {
        switch (xmlStreamReader.getEventType()) {
            case XMLStreamConstants.START_ELEMENT:
                System.out.println("Found start of element: " + xmlStreamReader.getLocalName());
                // Check if we are at the start of a <book> element
                if ("book".equals(xmlStreamReader.getLocalName())) {
                    int bookId = Integer.parseInt(xmlStreamReader.getAttributeValue("", "id"));
                    String bookTitle = xmlStreamReader.getElementText();
                    bookTitlesById.put(bookId, bookTitle);
                }
                break;
            // A bunch of other things are possible : comments, processing instructions, Whitespace...
            default:
                break;
        }
        xmlStreamReader.next();
    }

    System.out.println(bookTitlesById);
}

Cela produit:

Found start of element: library
Found start of element: book
Found start of element: book
Found start of element: notABook
{1=Effective Java, 2=Java Concurrency In Practice}

Dans cet exemple, il faut faire attention à quelques choses:

  1. L'utilisation de xmlStreamReader.getAttributeValue fonctionne car nous avons vérifié en premier que l'analyseur est dans l'état START_ELEMENT . Dans d' autres Etats Evey (sauf ATTRIBUTES ), l'analyseur est chargé de lancer IllegalStateException , car les attributs ne peuvent apparaître au début des éléments.

  2. Il en va de même pour xmlStreamReader.getTextContent() , cela fonctionne car nous sommes à un START_ELEMENT et nous savons dans ce document que l'élément <book> n'a pas de nœud enfant non textuel.

Pour l'analyse de documents plus complexes (éléments plus profonds, imbriqués, ...), il est BookParser de "déléguer" l'analyseur à des sous-méthodes ou à d'autres objets, par exemple, avoir une classe ou une méthode BookParser et traiter tous les éléments. de START_ELEMENT à END_ELEMENT de la balise XML du livre.

On peut également utiliser un objet Stack pour conserver des données importantes dans l’arbre.