How to read and write XML files?
Here is a quick DOM example that shows how to read and write a simple xml file with its 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>
and the 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)>
First import these:
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.*;
Here are a few variables you will need:
private String role1 = null;private String role2 = null;private String role3 = null;private String role4 = null;private ArrayList<String> rolev;
Here is a reader (String xml is the name of your xml file):
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; }
And here a writer:
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 is here:
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;}
Add a few accessors and mutators and you are done!
Writing XML using JAXB (Java Architecture for 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;@XmlRootElementpublic 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(); } }}
The above answer only deal with DOM parser (that normally reads the entire file in memory and parse it, what for a big file is a problem), you could use a SAX parser that uses less memory and is faster (anyway that depends on your code).
SAX parser callback some functions when it find a start of element, end of element, attribute, text between elements, etc, so it can parse the document and at the same time youget what you need.
Some example code:
http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/