Come leggere e scrivere file xml?

Devo leggere e scrivere da e verso un file XML . Qual è il modo più semplice per leggere e scrivere file XML usando Java?

Ecco un rapido esempio DOM che mostra come leggere e scrivere un semplice file xml con il suo dtd:

   User Author Admin   

e il dtd:

       

Prima importa questi:

 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.*; 

Ecco alcune variabili che ti serviranno:

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

Ecco un lettore (String xml è il nome del tuo file xml):

 public boolean readXML(String xml) { rolev = new ArrayList(); 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; } 

E qui uno scrittore:

 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 { Transformsr tr = TransformsrFactory.newInstance().newTransformsr(); 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 (TransformsrException 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 è qui:

 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; } 

Aggiungi alcuni accessori e mutatori e il gioco è fatto!

La risposta sopra tratta solo con parser DOM (che normalmente legge l’intero file in memoria e lo analizza, per un grande file c’è un problema), potresti usare un parser SAX che usa meno memoria ed è più veloce (comunque dipende dal tuo codice).

Il parser SAX richiama alcune funzioni quando trova un inizio di elemento, fine dell’elemento, attributo, testo tra gli elementi, ecc. In modo che possa analizzare il documento e allo stesso tempo ottenere ciò di cui hai bisogno.

Qualche esempio di codice:

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

Scrivere XML usando JAXB (Java Architecture per XML Binding):

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(); } } } 

Le risposte riguardano solo DOM / SAX e un’implementazione di copia incolla di un esempio JAXB.

Tuttavia, manca una grande area di quando si utilizza XML. In molti progetti / programmi è necessario archiviare / recuperare alcune strutture di dati di base. Il tuo programma ha già una class per i tuoi oggetti business / strutture di dati belle e lucenti, vuoi solo un modo comodo per convertire questi dati in una struttura XML in modo da poter fare più magia su di essa (memorizzare, caricare, inviare, manipolare con XSLT) .

Qui è dove XStream brilla. È sufficiente annotare le classi contenenti i dati oppure, se non si desidera modificare tali classi, configurare un’istanza XStream per il marshalling (oggetti -> xml) o unmarshalling (xml -> oggetti).

XStream internamente utilizza i metodi reflection, readObject e readResolve della serializzazione degli oggetti Java standard.

Ottieni un buon e veloce tutorial qui :

Per dare una breve panoramica di come funziona, fornisco anche del codice di esempio che esegue marshall e unmarshalls su una struttura di dati. Il marshalling / unmarshalling avviene tutto nel metodo main , il resto è solo codice per generare alcuni oggetti di test e popolare alcuni dati. È semplicissimo configurare l’istanza xStream e il marshalling / unmarshalling viene eseguito con una riga di codice ciascuna.

 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 stock = new ArrayList(); Customer add(Good g) { stock.add(g); return this; } } } 

Ok, avendo già DOM, JaxB e XStream nell’elenco delle risposte, c’è ancora un modo completamente diverso di leggere e scrivere XML: Proiezione dei dati È ansible disaccoppiare la struttura XML e la struttura Java utilizzando una libreria che fornisce viste leggibili e scrivibili ai dati XML come interfacce Java. Dalle esercitazioni :

Dato qualche codice XML reale:

      

Con la proiezione dei dati è ansible definire un’interfaccia di proiezione:

 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(); } 

E usa le istanze di questa interfaccia proprio come i POJO:

 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()); } 

Questo funziona anche per la creazione di XML, le espressioni XPath possono essere modificabili.

SAX parser SAX funziona in modo diverso con un parser DOM , non carica alcun documento XML in memoria né crea alcuna rappresentazione dell’object del documento XML . Invece, il parser SAX usa la funzione di callback org.xml.sax.helpers.DefaultHandler per informare i clienti della struttura del documento XML .

SAX Parser è più veloce e utilizza meno memoria del parser DOM . Vedi i seguenti metodi di callback SAX :

startDocument() e endDocument() – Metodo chiamato all’inizio e alla fine di un documento XML. startElement() e endElement() – Metodo chiamato all’inizio e alla fine di un elemento del documento. characters() – Metodo chiamato con il contenuto del testo tra i tag di inizio e di fine di un elemento di documento XML.

  1. File XML

Crea un semplice file XML.

    yong mook kim mkyong 100000   low yin fong fong fong 200000   
  1. Parser XML:

File Java Usa parser SAX per analizzare il file 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(); } } } 

Risultato

Start Element: azienda
Start Element: staff
Elemento iniziale: nome
Nome: yong
End Element: firstname
Inizia elemento: cognome
Cognome: mook kim
End Element: lastname
Elemento iniziale: nickname
Nick Nome: Mkyong
Elemento finale: soprannome
e così via…

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