Comment lire et écrire des fichiers xml?


Je dois lire et écrire vers et depuis un fichier XML. Quelle est la façon la plus simple de lire et d'écrire des fichiers XML en utilisant Java?

Author: Paolo Forgia, 2011-09-10

6 answers

Voici un exemple de DOM rapide qui montre comment lire et écrire un fichier xml simple avec sa dtd:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE roles SYSTEM "roles.dtd">
<roles>
    <role1>User</role1>
    <role2>Author</role2>
    <role3>Admin</role3>
    <role4/>
</roles>

Et la dtd:

<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT roles (role1,role2,role3,role4)>
<!ELEMENT role1 (#PCDATA)>
<!ELEMENT role2 (#PCDATA)>
<!ELEMENT role3 (#PCDATA)>
<!ELEMENT role4 (#PCDATA)>

Importez d'abord ces:

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.xml.sax.*;
import org.w3c.dom.*;

Voici quelques variables dont vous aurez besoin:

private String role1 = null;
private String role2 = null;
private String role3 = null;
private String role4 = null;
private ArrayList<String> rolev;

Voici un lecteur (String xml est le nom de votre fichier xml):

public boolean readXML(String xml) {
        rolev = new ArrayList<String>();
        Document dom;
        // Make an  instance of the DocumentBuilderFactory
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            // use the factory to take an instance of the document builder
            DocumentBuilder db = dbf.newDocumentBuilder();
            // parse using the builder to get the DOM mapping of the    
            // XML file
            dom = db.parse(xml);

            Element doc = dom.getDocumentElement();

            role1 = getTextValue(role1, doc, "role1");
            if (role1 != null) {
                if (!role1.isEmpty())
                    rolev.add(role1);
            }
            role2 = getTextValue(role2, doc, "role2");
            if (role2 != null) {
                if (!role2.isEmpty())
                    rolev.add(role2);
            }
            role3 = getTextValue(role3, doc, "role3");
            if (role3 != null) {
                if (!role3.isEmpty())
                    rolev.add(role3);
            }
            role4 = getTextValue(role4, doc, "role4");
            if ( role4 != null) {
                if (!role4.isEmpty())
                    rolev.add(role4);
            }
            return true;

        } catch (ParserConfigurationException pce) {
            System.out.println(pce.getMessage());
        } catch (SAXException se) {
            System.out.println(se.getMessage());
        } catch (IOException ioe) {
            System.err.println(ioe.getMessage());
        }

        return false;
    }

Et ici un écrivain:

public void saveToXML(String xml) {
    Document dom;
    Element e = null;

    // instance of a DocumentBuilderFactory
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
        // use factory to get an instance of document builder
        DocumentBuilder db = dbf.newDocumentBuilder();
        // create instance of DOM
        dom = db.newDocument();

        // create the root element
        Element rootEle = dom.createElement("roles");

        // create data elements and place them under root
        e = dom.createElement("role1");
        e.appendChild(dom.createTextNode(role1));
        rootEle.appendChild(e);

        e = dom.createElement("role2");
        e.appendChild(dom.createTextNode(role2));
        rootEle.appendChild(e);

        e = dom.createElement("role3");
        e.appendChild(dom.createTextNode(role3));
        rootEle.appendChild(e);

        e = dom.createElement("role4");
        e.appendChild(dom.createTextNode(role4));
        rootEle.appendChild(e);

        dom.appendChild(rootEle);

        try {
            Transformer tr = TransformerFactory.newInstance().newTransformer();
            tr.setOutputProperty(OutputKeys.INDENT, "yes");
            tr.setOutputProperty(OutputKeys.METHOD, "xml");
            tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            tr.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "roles.dtd");
            tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

            // send DOM to file
            tr.transform(new DOMSource(dom), 
                                 new StreamResult(new FileOutputStream(xml)));

        } catch (TransformerException te) {
            System.out.println(te.getMessage());
        } catch (IOException ioe) {
            System.out.println(ioe.getMessage());
        }
    } catch (ParserConfigurationException pce) {
        System.out.println("UsersXML: Error trying to instantiate DocumentBuilder " + pce);
    }
}

GetTextValue est ici:

private String getTextValue(String def, Element doc, String tag) {
    String value = def;
    NodeList nl;
    nl = doc.getElementsByTagName(tag);
    if (nl.getLength() > 0 && nl.item(0).hasChildNodes()) {
        value = nl.item(0).getFirstChild().getNodeValue();
    }
    return value;
}

Ajoutez quelques accesseurs et mutateurs et vous avez terminé!

 120
Author: Costis Aivalis, 2014-10-29 23:03:56

La réponse ci-dessus ne traite que de l'analyseur DOM (qui lit normalement le fichier entier en mémoire et l'analyse, ce qui pour un gros fichier est un problème), vous pouvez utiliser un analyseur SAX qui utilise moins de mémoire et est plus rapide (de toute façon cela dépend de votre code).

SAX parser callback certaines fonctions lorsqu'il trouve un début d'élément, une fin d'élément, un attribut, du texte entre les éléments, etc., afin qu'il puisse analyser le document et en même temps vous obtenez ce dont vous avez besoin.

Quelques exemples code:

Http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/

 10
Author: Diego C Nascimento, 2013-08-19 03:26:12

Écriture XML à l'aide de JAXB (Architecture Java pour la liaison XML):

Http://www.mkyong.com/java/jaxb-hello-world-example/

package com.mkyong.core;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Customer {

    String name;
    int age;
    int id;

    public String getName() {
        return name;
    }

    @XmlElement
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    @XmlElement
    public void setAge(int age) {
        this.age = age;
    }

    public int getId() {
        return id;
    }

    @XmlAttribute
    public void setId(int id) {
        this.id = id;
    }

} 

package com.mkyong.core;

import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class JAXBExample {
    public static void main(String[] args) {

      Customer customer = new Customer();
      customer.setId(100);
      customer.setName("mkyong");
      customer.setAge(29);

      try {

        File file = new File("C:\\file.xml");
        JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

        // output pretty printed
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        jaxbMarshaller.marshal(customer, file);
        jaxbMarshaller.marshal(customer, System.out);

          } catch (JAXBException e) {
        e.printStackTrace();
          }

    }
}
 9
Author: Ran Adler, 2015-11-29 06:33:16

Les réponses ne couvrent que DOM / SAX et une implémentation copier-coller d'un exemple JAXB.

Cependant, une grande zone de lorsque vous utilisez XML est manquante. Dans beaucoup de projets / programmes, il est nécessaire de stocker / récupérer certaines structures de base de données. Votre programme a déjà une classe pour vos objets métier / structures de données sympas et brillants, vous voulez juste un moyen confortable de convertir ces données en une structure XML afin que vous puissiez faire plus de magie dessus (stocker, charger, envoyer, manipuler avec XSLT).

C'est là que XStream brille. Vous annotez simplement les classes contenant vos données, ou si vous ne souhaitez pas modifier ces classes, vous configurez une instance XStream pour marshalling (objects -> xml) ou unmarshalling (xml -> objects).

En interne, XStream utilise reflection, les méthodes readObject et readResolve de la sérialisation d'objets Java standard.

Vous obtenez un bon et rapide tutoriel ici:

Pour donner un bref aperçu de son fonctionnement, je fournissez un exemple de code qui marshalls et unmarshalls une structure de données. Le marshalling / unmarshalling se produit tout dans la méthode main, le reste n'est que du code pour générer des objets de test et leur fournir des données. Il est super simple de configurer l'instance xStream et le marshalling / unmarshalling se fait avec une ligne de code chacune.

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.XStream;

public class XStreamIsGreat {

  public static void main(String[] args) {
    XStream xStream = new XStream();
    xStream.alias("good", Good.class);
    xStream.alias("pRoDuCeR", Producer.class);
    xStream.alias("customer", Customer.class);

    Producer a = new Producer("Apple");
    Producer s = new Producer("Samsung");
    Customer c = new Customer("Someone").add(new Good("S4", 10, new BigDecimal(600), s))
        .add(new Good("S4 mini", 5, new BigDecimal(450), s)).add(new Good("I5S", 3, new BigDecimal(875), a));
    String xml = xStream.toXML(c); // objects -> xml
    System.out.println("Marshalled:\n" + xml);
    Customer unmarshalledCustomer = (Customer)xStream.fromXML(xml); // xml -> objects
  }

  static class Good {
    Producer producer;

    String name;

    int quantity;

    BigDecimal price;

    Good(String name, int quantity, BigDecimal price, Producer p) {
      this.producer = p;
      this.name = name;
      this.quantity = quantity;
      this.price = price;
    }

  }

  static class Producer {
    String name;

    public Producer(String name) {
      this.name = name;
    }
  }

  static class Customer {
    String name;

    public Customer(String name) {
      this.name = name;
    }

    List<Good> stock = new ArrayList<Good>();

    Customer add(Good g) {
      stock.add(g);
      return this;
    }
  }
}
 3
Author: Matthias, 2013-11-14 13:59:34

Ok, ayant déjà DOM, JaxB et XStream dans la liste des réponses, il existe toujours une manière complètement différente de lire et d'écrire XML: Data projection Vous pouvez découpler la structure XML et la structure Java en utilisant une bibliothèque qui fournit des vues en lecture et en écriture aux données XML en tant qu'interfaces Java. Des tutoriels :

Étant donné certains XML du monde réel:

<weatherdata>
  <weather
    ... 
    degreetype="F"
    lat="50.5520210266113" lon="6.24060010910034" 
    searchlocation="Monschau, Stadt Aachen, NW, Germany" 
            ... >
    <current ... skytext="Clear" temperature="46"/>
  </weather>
</weatherdata>

Avec la projection de données, vous pouvez définir une interface de projection:

public interface WeatherData {

@XBRead("/weatherdata/weather/@searchlocation")   
String getLocation();

@XBRead("/weatherdata/weather/current/@temperature")
int getTemperature();

@XBRead("/weatherdata/weather/@degreetype")
String getDegreeType();

@XBRead("/weatherdata/weather/current/@skytext")
String getSkytext();

/**
 * This would be our "sub projection". A structure grouping two attribute
 * values in one object.
 */
interface Coordinates {
    @XBRead("@lon")
    double getLongitude();

    @XBRead("@lat")
    double getLatitude();
}

@XBRead("/weatherdata/weather")
Coordinates getCoordinates();
}

Et utiliser des instances de cette interface comme POJOs:

private void printWeatherData(String location) throws IOException {

final String BaseURL = "http://weather.service.msn.com/find.aspx?outputview=search&weasearchstr=";

// We let the projector fetch the data for us
WeatherData weatherData = new XBProjector().io().url(BaseURL + location).read(WeatherData.class);

// Print some values
System.out.println("The weather in " + weatherData.getLocation() + ":");
System.out.println(weatherData.getSkytext());
System.out.println("Temperature: " + weatherData.getTemperature() + "°"
                                   + weatherData.getDegreeType());

// Access our sub projection
Coordinates coordinates = weatherData.getCoordinates();
System.out.println("The place is located at " + coordinates.getLatitude() + ","
                                              + coordinates.getLongitude());
}

Cela fonctionne même pour créer du XML, les expressions XPath peuvent être inscriptibles.

 1
Author: Cfx, 2014-12-27 21:52:43

SAX l'analyseur fonctionne différemment avec un analyseur DOM, il ne charge aucun document XML en mémoire ni ne crée aucune représentation d'objet du document XML. Au lieu de cela, l'analyseur SAX utilise la fonction de rappel org.xml.sax.helpers.DefaultHandler pour informer les clients de la structure du document XML.

SAX l'Analyseur est plus rapide et utilise moins de mémoire que les DOM analyseur. Voir les méthodes de rappel SAX suivantes:

startDocument() et endDocument() – Méthode appelée au début et à la fin d'un document XML. startElement() et endElement() – Méthode appelée au début et à la fin d'un élément de document. characters() – Méthode appelée avec le contenu du texte entre les balises de début et de fin d'un élément de document XML.

  1. Fichier XML

Créez un simple fichier XML.

<?xml version="1.0"?>
<company>
    <staff>
        <firstname>yong</firstname>
        <lastname>mook kim</lastname>
        <nickname>mkyong</nickname>
        <salary>100000</salary>
    </staff>
    <staff>
        <firstname>low</firstname>
        <lastname>yin fong</lastname>
        <nickname>fong fong</nickname>
        <salary>200000</salary>
    </staff>
</company>
  1. Analyseur XML:

Fichier Java Utilisez l'analyseur SAX pour analyser le fichier XML.

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ReadXMLFile {
    public static void main(String argv[]) {

        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            DefaultHandler handler = new DefaultHandler() {
                boolean bfname = false;
                boolean blname = false;
                boolean bnname = false;
                boolean bsalary = false;

                public void startElement(String uri, String localName,String qName, 
                            Attributes attributes) throws SAXException {

                    System.out.println("Start Element :" + qName);

                    if (qName.equalsIgnoreCase("FIRSTNAME")) {
                        bfname = true;
                    }

                    if (qName.equalsIgnoreCase("LASTNAME")) {
                        blname = true;
                    }

                    if (qName.equalsIgnoreCase("NICKNAME")) {
                        bnname = true;
                    }

                    if (qName.equalsIgnoreCase("SALARY")) {
                        bsalary = true;
                    }

                }

                public void endElement(String uri, String localName,
                    String qName) throws SAXException {

                    System.out.println("End Element :" + qName);

                }

                public void characters(char ch[], int start, int length) throws SAXException {

                    if (bfname) {
                        System.out.println("First Name : " + new String(ch, start, length));
                        bfname = false;
                    }

                    if (blname) {
                        System.out.println("Last Name : " + new String(ch, start, length));
                        blname = false;
                    }

                    if (bnname) {
                        System.out.println("Nick Name : " + new String(ch, start, length));
                        bnname = false;
                    }

                    if (bsalary) {
                        System.out.println("Salary : " + new String(ch, start, length));
                        bsalary = false;
                    }

                }

            };

            saxParser.parse("c:\\file.xml", handler);

        } catch (Exception e) {
           e.printStackTrace();
        }

    }

}

Résultat

Élément de démarrage: société
Élément de départ: staff
Élément de début: firstname
Prénom : yong
Élément de fin: firstname
Élément de début: lastname
Nom de famille : mook kim
Élément de fin: lastname
Élément de départ: pseudo
Nom d'emprunt: mkyong
Élément de fin: surnom
et ainsi de suite...

Source(MyKong) - http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/

 0
Author: JavaDragon, 2018-07-02 12:19:12