Prise en charge des bibliothèques XML en Java

Prise en charge des bibliothèques XML en Java

1. introduction

Dans cet article, nous allons comparer les bibliothèques XML XML et les API.

Ceci est le deuxième article de la série sur le support Java pour XML, si vous souhaitez approfondir le support XPath en Java, jetez un œil àthe previous article.

2. Vue d'ensemble

Nous allons maintenant aller plus loin dans le support du monde XML et pour cela, nous allons commencer par expliquer le plus simplement possible toutes les initiales du sujet.

Dans le support Java XML, nous pouvons trouver quelques définitions d’API, chacune ayant ses avantages et ses inconvénients.

  • SAX: Il s'agit d'une API d'analyse basée sur les événements, elle fournit un accès de bas niveau, est efficace en mémoire et plus rapide que DOM car elle ne charge pas toute l'arborescence du document en mémoire mais elle ne prend pas en charge la navigation comme celui fourni par XPath, bien qu'il soit plus efficace, il est également plus difficile à utiliser.

  • DOM: Il s'agit d'un analyseur basé sur un modèle qui charge un document d'arborescence en mémoire, nous avons donc l'ordre des éléments d'origine, nous pouvons naviguer dans notre document dans les deux sens, il fournit une API pour la lecture et l'écriture, il offre une manipulation XML et il est très facile à utiliser bien que le prix soit une pression élevée sur les ressources mémoire.

  • StAX: Il offre la facilité du DOM et l'efficacité de SAX mais il manque de certaines fonctionnalités fournies par DOM comme la manipulation XML et il nous permet seulement de faire avancer le document.

  • JAXB: Cela nous permet de naviguer dans le document dans les deux sens, il est plus efficace que DOM, il permet la conversion de XML en types java et il prend en charge la manipulation XML mais il ne peut analyser qu'un document XML valide.

Vous pouvez toujours trouver des références à JAXP mais la dernière version de ce projet date de mars 2013 et elle est pratiquement morte.

XML Apis Table

Tableau des API XML

3. Le XML

Dans cette section, nous allons voir les implémentations les plus populaires, afin de pouvoir tester de vrais échantillons de travail et vérifier les différences entre eux.

Dans les exemples suivants, nous allons travailler avec un simple fichier XML avec une structure comme celle-ci:


    
        Guava
        Introduction to Guava
        04/04/2016
        GuavaAuthor
    
    ...

4. DOM4J

Nous allons commencer par jeter un œil à ce que nous pouvons faire avecDOM4J et pour cet exemple nous devons ajouter la dernière version de cedependency.

C'est l'une des bibliothèques les plus populaires pour travailler avec les fichiersXML, car elle nous permet d'effectuer une lecture bidirectionnelle, de créer de nouveaux documents et de mettre à jour les fichiers existants.

DOM4J peut fonctionner avecDOM,SAX,XPath etXLST. SAX est pris en charge viaJAXP. __

Jetons un coup d'œil ici, par exemple, comment pouvons-nous sélectionner un élément filtrant par un identifiant donné.

SAXReader reader = new SAXReader();
Document document = reader.read(file);
List elements = document.selectNodes("//*[@tutId='" + id + "']");
return elements.get(0);

La classeSAXReader est responsable de la création d'une arborescenceDOM4J à partir des événements d'analyse deSAX. Une fois que nous avons unorg.dom4j.Document, il suffit d'appeler la méthode nécessaire et de lui passer l'expressionXPath sous forme deString.

Nous pouvons charger un document existant, modifier son contenu, puis mettre à jour le fichier d'origine.

for (Node node : nodes) {
    Element element = (Element)node;
    Iterator iterator = element.elementIterator("title");
    while (iterator.hasNext()) {
        Element title =(Element)iterator.next();
        title.setText(title.getText() + " updated");
    }
}
XMLWriter writer = new XMLWriter(
  new FileWriter(new File("src/test/resources/example_updated.xml")));
writer.write(document);
writer.close();

Dans l'exemple ci-dessus, nous modifions le contenu de chaque titre et créons un nouveau fichier.

Remarquez ici combien il est simple d'obtenir lesnode de tous les titres dans une liste en appelantelementIterator et en passant le nom desnode.

Une fois notre contenu modifié, nous utiliserons leXMLWriter qui prend un arbreDOM4J et le formate en un flux en tant queXML.

Créer un nouveau document à partir de rien est aussi simple que nous le voyons ci-dessous.

Document document = DocumentHelper.createDocument();
Element root = document.addElement("XMLTutorials");
Element tutorialElement = root.addElement("tutorial").addAttribute("tutId", "01");
tutorialElement.addAttribute("type", "xml");
tutorialElement.addElement("title").addText("XML with Dom4J");
...
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(
  new FileWriter(new File("src/test/resources/example_new.xml")), format);
writer.write(document);
writer.close();

DocumentHelper nous donne une collection de méthodes à utiliser parDOM4J, commecreateDocument qui crée un document vide pour commencer à travailler avec lui.

Nous pouvons créer autant d'attributs ou d'éléments que nécessaire avec les méthodes fournies parDOM4J, et une fois notre document terminé, nous l'écrivons simplement dans un fichier comme nous l'avons fait avec le cas de mise à jour précédent.

5. JDOM

Afin de travailler avecJDOM,, nous devons ajouter cedependency à notre pom.

Le style de travail deJDOM’s est assez similaire àDOM4J’s, nous allons donc jeter un coup d'œil à quelques exemples:

SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(this.getFile());
Element tutorials = doc.getRootElement();
List titles = tutorials.getChildren("tutorial");

Dans l'exemple ci-dessus, nous récupérons tous les éléments de l'élément racine d'une manière très simple, comme nous pouvons le faire avecDOM4J:

SAXBuilder builder = new SAXBuilder();
Document document = (Document) builder.build(file);
String filter = "//*[@tutId='" + id + "']";
XPathFactory xFactory = XPathFactory.instance();
XPathExpression expr = xFactory.compile(filter, Filters.element());
List node = expr.evaluate(document);

Encore une fois, ici dans le code ci-dessus, nous avons unSAXBuilder créant une instanceDocument à partir d'un fichier donné. Nous récupérons un élément par son attributtutId en passant une expressionXPath auxXPathFactory fournis parJDOM2.

6. StAX

Maintenant, nous allons voir comment nous pourrions récupérer tous les éléments de notre élément racine en utilisant lesStax API. Stax est inclus dans lesJDK depuis Java 6, vous n'avez donc pas besoin d'ajouter de dépendances.

Tout d'abord, nous devons créer une classeTutorial:

public class Tutorial {
    private String tutId;
    private String type;
    private String title;
    private String description;
    private String date;
    private String author;

    // standard getters and setters
}

et alors nous sommes prêts à suivre avec:

List tutorials = new ArrayList<>();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader eventReader = factory.createXMLEventReader(new FileReader(this.getFile()));
Tutorial current;
while (eventReader.hasNext()) {
    XMLEvent event = eventReader.nextEvent();
    switch (event.getEventType()) {
        case XMLStreamConstants.START_ELEMENT:
            StartElement startElement = event.asStartElement();
            String qName = startElement.getName().getLocalPart();
            ...
            break;
        case XMLStreamConstants.CHARACTERS:
            Characters characters = event.asCharacters();
            ...
            break;
        case XMLStreamConstants.END_ELEMENT:
            EndElement endElement = event.asEndElement();

            // check if we found the closing element
            // close resources that need to be explicitly closed
            break;
    }
}

Dans l'exemple ci-dessus, afin de nous aider à récupérer les informations, nous devions créer une classe pour stocker les données récupérées.

Pour lire le document, nous avons déclaré ce que l’on appelle des gestionnaires d’événements et nous les avons utilisés pour naviguer dans notre document. N'oubliez pas que les implémentations SAX ne fournissent pas de navigation bidirectionnelle. Comme vous pouvez le voir ici, il reste beaucoup à faire pour récupérer une simple liste d’éléments.

7. JAXB

JAXB est inclus avec lesJDK, ainsi que Xerces, ne nécessitent aucune dépendance supplémentaire pour celui-ci.

Il est très simple de charger, créer et manipuler des informations à partir d’un fichierXML à l’aide deJAXB.

Nous avons juste besoin de créer les bonnes entités Java pour lier lesXML et c'est tout.

JAXBContext jaxbContext = JAXBContext.newInstance(Tutorials.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Tutorials tutorials = (Tutorials) jaxbUnmarshaller.unmarshal(this.getFile());

Dans l'exemple ci-dessus, nous chargeons notre fichierXML dans notre objet et à partir de là, nous pouvons tout gérer comme une structure Java normale;

Pour créer un nouveau document, il suffit de le lire mais en procédant de manière inverse, comme dans le code ci-dessous.

Tout d'abord, nous allons modifier notre classeTutorial pour ajouter des annotationsJAXB àgetters etsetters:

public class Tutorial {
    ...

    public String getTutId() {
        return tutId;
    }

    @XmlAttribute
    public void setTutId(String tutId) {
        this.tutId = tutId;
    }
    ...
    @XmlElement
    public void setTitle(String title) {
        this.title = title;
    }
    ...
}

@XmlRootElement
public class Tutorials {
    private List tutorial;

    // standard getters and setters with @XmlElement annotation
}

Avec@XmlRootElement, nous définissons quel objet va représenter le nœud racine de notre document, puis nous utilisons@XmlAttribute ou@XmlElement pour définir si cet attribut représente un attribut d'un nœud ou un élément de le document.

Ensuite, nous pouvons suivre avec:

Tutorials tutorials = new Tutorials();
tutorials.setTutorial(new ArrayList<>());
Tutorial tut = new Tutorial();
tut.setTutId("01");
...
tutorials.getTutorial().add(tut);
JAXBContext jaxbContext = JAXBContext.newInstance(Tutorials.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(tutorials, file);

Comme vous pouvez le constater, la liaison d'un fichier XML à des objets Java est le moyen le plus simple de gérer ce type de fichiers.

8. Prise en charge des expressions XPath

Pour créer des expressions XPath complexes, nous pouvons utiliser Jaxen. Il s'agit d'une bibliothèque XPath open source adaptable à de nombreux modèles d'objets différents, y comprisDOM,XOM,DOM4J etJDOM.

Nous pouvons créer des expressions XPath et les compiler avec de nombreux documents pris en charge.

String expression = "/tutorials/tutorial";
XPath path = new DOMXPath(expression);
List result = path.selectNodes(xmlDocument);

Pour que cela fonctionne, nous devons ajouter cedependency à notre projet.

9. Conclusion

Comme vous pouvez le voir, il existe de nombreuses options pour travailler avecXML, selon les exigences de votre application, vous pouvez travailler avec l'une d'entre elles ou vous devrez peut-être choisir entre efficacité et simplicité.

Vous pouvez trouver les exemples de travail complets pour cet article dans notre dépôt githere.