I need to generate an XML file from just having a map, which contains the parent element and his children.
Map looks like this:
Map<String, List<Element>> elementMap = new LinkedHashMap<String, List<Element>>();
root: el1 el2 el3 el4 // root is the parent and el1... are his children.
el1: el5 el6
el2: el7 el8
Expected XML Model:
<root>
<el1>
<el5></el5>
<el6></el6>
</el1>
<el2>
<el7></el7>
<el8></el87>
</el2>
<el3></el3>
<el4></el4>
</root>
Can you give me some tips, algorithms how I could generate that XML?
I thought about recursion, but I don't know where to start.
Any suggestions?
Your thoughts were good.
You have to use iterating every one of your map keys and generate the list of elements based on values from this key. The result should be append to the general document.
You haven't posted your Element class. I will show some example based on Map<String, List<String>> elementMap.
Here is code snippet:
import com.epam.lab.model.exceptions.CreateDocumentConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class XmlBuilder {
private DocumentBuilder builder;
private Document doc;
/**
* Constructs an item list builder.
*
* #throws CreateDocumentConfigurationException
*/
public XmlBuilder() throws CreateDocumentConfigurationException {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new CreateDocumentConfigurationException("exception create new document", e);
}
}
/**
* Builds a DOM document for an array list of items.
*
* #param elementMap map of items.
* #return a DOM document describing the items.
*/
public Document build(Map<String, List<String>> elementMap) {
doc = builder.newDocument();
doc.appendChild(createItems(elementMap));
return doc;
}
/**
* Builds a DOM element for an array list of items.
*
* #param elementMap the map of items
* #return a DOM element describing the items
*/
private Element createItems(Map<String, List<String>> elementMap) {
Element e = null;
for (Map.Entry<String, List<String>> anItem : elementMap.entrySet()) {
e = doc.createElement(anItem.getKey());
for (Node node : createItemsList(anItem.getValue())) {
e.appendChild(node);
}
}
return e;
}
private List<Node> createItemsList(List<String> items) {
List<Node> result = new ArrayList<>();
for (String item : items) {
Element item1 = createItem(item);
result.add(item1);
}
return result;
}
/**
* Builds a DOM element for an item.
*
* #param anItem the item
* #return a DOM element describing the item
*/
private Element createItem(String anItem) {
// if you need some text element to your element - just append it here.
return doc.createElement(anItem);
}
/**
* Builds the text content for document
*
* #param name element
* #param text content
* #return text element
*/
private Element createTextElement(String name, String text) {
Text t = doc.createTextNode(text);
Element e = doc.createElement(name);
e.appendChild(t);
return e;
}
private String generateXmlContent(Map<String, List<String>> elementMap) {
String content;
Document doc = build(elementMap);
DOMImplementation impl = doc.getImplementation();
DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS", "3.0");
LSSerializer ser = implLS.createLSSerializer();
ser.getDomConfig().setParameter("format-pretty-print", true);
content = ser.writeToString(doc);
return content;
}
public void writeToXmlFile(String xmlContent) {
File theDir = new File("./output");
if (!theDir.exists())
theDir.mkdir();
String fileName = "./output/" + this.getClass().getSimpleName() + "_"
+ Calendar.getInstance().getTimeInMillis() + ".xml";
try (OutputStream stream = new FileOutputStream(new File(fileName))) {
try (OutputStreamWriter out = new OutputStreamWriter(stream, StandardCharsets.UTF_16)) {
out.write(xmlContent);
out.write("\n");
}
} catch (IOException ex) {
System.err.println("Cannot write to file!" + ex.getMessage());
}
}
public static void main(String[] args) throws CreateDocumentConfigurationException {
XmlBuilder xmlBuilder = new XmlBuilder();
Map<String, List<String>> map = MapFactory.mapOf(MapFactory.entry("root", Arrays.asList("element1", "element2", "element3")));
String xmlContent = xmlBuilder.generateXmlContent(map);
xmlBuilder.writeToXmlFile(xmlContent);
}
}
After generating XML document you have to write it to file.
But you have to prepare XML content before writing, something like:
private String generateXmlContent(Map<String, List<String>> elementMap) {
String content;
Document doc = build(elementMap);
DOMImplementation impl = doc.getImplementation();
DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS", "3.0");
LSSerializer ser = implLS.createLSSerializer();
ser.getDomConfig().setParameter("format-pretty-print", true);
content = ser.writeToString(doc);
return content;
}
And finally writing to file can look like:
public void writeToXmlFile(String xmlContent) {
File theDir = new File("./output");
if (!theDir.exists())
theDir.mkdir();
String fileName = "./output/" + this.getClass().getSimpleName() + "_"
+ Calendar.getInstance().getTimeInMillis() + ".xml";
try (OutputStream stream = new FileOutputStream(new File(fileName))) {
try (OutputStreamWriter out = new OutputStreamWriter(stream, StandardCharsets.UTF_16)) {
out.write(xmlContent);
out.write("\n");
}
} catch (IOException ex) {
System.err.println("Cannot write to file!", ex);
}
}
Utility factory for creating Map, based on literals:
public class MapFactory {
// Creates a map from a list of entries
#SafeVarargs
public static <K, V> Map<K, V> mapOf(Map.Entry<K, V>... entries) {
LinkedHashMap<K, V> map = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : entries) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}
// Creates a map entry
public static <K, V> Map.Entry<K, V> entry(K key, V value) {
return new AbstractMap.SimpleEntry<>(key, value);
}
}
After executing main() I have got following XML file XmlBuilder_1456910256665.xml:
<?xml version="1.0" encoding="UTF-16"?>
<root>
<element1/>
<element2/>
<element3/>
</root>
You can use below fuction for converting the Map to an XML string.
public static String maptoXML(Object hashMap) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
XMLEncoder xmlEncoder = new XMLEncoder(bos);
xmlEncoder.writeObject(hashMap);
xmlEncoder.close();
return bos.toString();
}
Ref:http://pritomkumar.blogspot.in/2014/05/convert-map-hashmap-or-listarraylist-to.html?m=1
Related
I have to read and write to and from an XML file. What is the easiest way to read and write XML files using Java?
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;
#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();
}
}
}
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 you
get what you need.
Some example code:
http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/
The answers only cover DOM / SAX and a copy paste implementation of a JAXB example.
However, one big area of when you are using XML is missing. In many projects / programs there is a need to store / retrieve some basic data structures. Your program has already a classes for your nice and shiny business objects / data structures, you just want a comfortable way to convert this data to a XML structure so you can do more magic on it (store, load, send, manipulate with XSLT).
This is where XStream shines. You simply annotate the classes holding your data, or if you do not want to change those classes, you configure a XStream instance for marshalling (objects -> xml) or unmarshalling (xml -> objects).
Internally XStream uses reflection, the readObject and readResolve methods of standard Java object serialization.
You get a good and speedy tutorial here:
To give a short overview of how it works, I also provide some sample code which marshalls and unmarshalls a data structure.
The marshalling / unmarshalling happens all in the main method, the rest is just code to generate some test objects and populate some data to them.
It is super simple to configure the xStream instance and marshalling / unmarshalling is done with one line of code each.
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;
}
}
}
Ok, already having DOM, JaxB and XStream in the list of answers, there is still a complete different way to read and write XML: Data projection You can decouple the XML structure and the Java structure by using a library that provides read and writeable views to the XML Data as Java interfaces. From the tutorials:
Given some real world XML:
<weatherdata>
<weather
...
degreetype="F"
lat="50.5520210266113" lon="6.24060010910034"
searchlocation="Monschau, Stadt Aachen, NW, Germany"
... >
<current ... skytext="Clear" temperature="46"/>
</weather>
</weatherdata>
With data projection you can define a projection interface:
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();
}
And use instances of this interface just like 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());
}
This works even for creating XML, the XPath expressions can be writable.
SAX parser is working differently with a DOM parser, it neither load any XML document into memory nor create any object representation of the XML document. Instead, the SAX parser use callback function org.xml.sax.helpers.DefaultHandler to informs clients of the XML document structure.
SAX Parser is faster and uses less memory than DOM parser.
See following SAX callback methods :
startDocument() and endDocument() – Method called at the start and end of an XML document.
startElement() and endElement() – Method called at the start and end of a document element.
characters() – Method called with the text contents in between the start and end tags of an XML document element.
XML file
Create a simple XML file.
<?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>
XML parser:
Java file Use SAX parser to parse the XML file.
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();
}
}
}
Result
Start Element :company
Start Element :staff
Start Element :firstname
First Name : yong
End Element :firstname
Start Element :lastname
Last Name : mook kim
End Element :lastname
Start Element :nickname
Nick Name : mkyong
End Element :nickname
and so on...
Source(MyKong) - http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/
I want to generate an xml file, as said in the title. The data that I need is stored in a database table in the form XML_NAME and XML_PARENT_NAME, which is the parent for XML_NAME.
Now, can you give me some ideas, algorithms, how to generate my xml file by only knowing these two things ?
Thanks in advance!
UPDATE:
XML Example:
<root>
<element1></element1>
<element2></element2>
<element3>
<child>
<text></text>
</child>
</element3>
</root>
Database model:
XML_NAME | XML_PARENT_NAME
root
element1 root
element2 root
element3 root
child element3
text child
I only have this DB entries and from these ones I need to costruct an xml file, which loooks like the above one.
Using XML Stream writer:
Here is a simple example that writes a series of events to disk, using a FileWriter:
XMLOutputFactory factory = XMLOutputFactory.newInstance();
try {
XMLStreamWriter writer = factory.createXMLStreamWriter(
new FileWriter("data\\output2.xml"));
writer.writeStartDocument();
writer.writeStartElement("document");
writer.writeStartElement("data");
writer.writeAttribute("name", "value");
writer.writeEndElement();
writer.writeEndElement();
writer.writeEndDocument();
writer.flush();
writer.close();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The result of executing this code is the following XML file:
<?xml version='1.0' encoding='utf-8'?>
<document><data name="value"></data> </document>
Ref:http://tutorials.jenkov.com/java-xml/stax-xmlstreamwriter.html
If you dont need values just use writeStartElement and writeEndElement
Also another option with child elements is:
Element root=new Element("CONFIGURATION");
Document doc=new Document();
Element child1=new Element("BROWSER");
child1.addContent("chrome");
Element child2=new Element("BASE");
child1.addContent("http:fut");
Element child3=new Element("EMPLOYEE");
child3.addContent(new Element("EMP_NAME").addContent("Anhorn, Irene"));
root.addContent(child1);
root.addContent(child2);
root.addContent(child3);
doc.setRootElement(root);
XMLOutputter outter=new XMLOutputter();
outter.setFormat(Format.getPrettyFormat());
outter.output(doc, new FileWriter(new File("myxml.xml")));
You can use an algorithm which #mlkammer suggested.
After collecting final map which contains all info you can write it to file.
For an example, your map looks as Map<String, List<String>> map.
After it, you can easily format and write it to file.
Here is code snippet:
import org.w3c.dom.*;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class XmlBuilder {
private DocumentBuilder builder;
private Document doc;
/**
* Constructs an item list builder.
*
* #throws CreateDocumentConfigurationException
*/
public XmlBuilder() throws CreateDocumentConfigurationException {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new CreateDocumentConfigurationException("exception create new document", e);
}
}
/**
* Builds a DOM document for an array list of items.
*
* #param elementMap map of items.
* #return a DOM document describing the items.
*/
public Document build(Map<String, List<String>> elementMap) {
doc = builder.newDocument();
doc.appendChild(createItems(elementMap));
return doc;
}
/**
* Builds a DOM element for an array list of items.
*
* #param elementMap the map of items
* #return a DOM element describing the items
*/
private Element createItems(Map<String, List<String>> elementMap) {
Element e = null;
for (Map.Entry<String, List<String>> anItem : elementMap.entrySet()) {
e = doc.createElement(anItem.getKey());
for (Node node : createItemsList(anItem.getValue())) {
e.appendChild(node);
}
}
return e;
}
private List<Node> createItemsList(List<String> items) {
List<Node> result = new ArrayList<>();
for (String item : items) {
Element item1 = createItem(item);
result.add(item1);
}
return result;
}
/**
* Builds a DOM element for an item.
*
* #param anItem the item
* #return a DOM element describing the item
*/
private Element createItem(String anItem) {
// if you need some text element to your element - just append it here.
return doc.createElement(anItem);
}
/**
* Builds the text content for document
*
* #param name element
* #param text content
* #return text element
*/
private Element createTextElement(String name, String text) {
Text t = doc.createTextNode(text);
Element e = doc.createElement(name);
e.appendChild(t);
return e;
}
private String generateXmlContent(Map<String, List<String>> elementMap) {
String content;
Document doc = build(elementMap);
DOMImplementation impl = doc.getImplementation();
DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS", "3.0");
LSSerializer ser = implLS.createLSSerializer();
ser.getDomConfig().setParameter("format-pretty-print", true);
content = ser.writeToString(doc);
return content;
}
public void writeToXmlFile(String xmlContent) {
File theDir = new File("./output");
if (!theDir.exists())
theDir.mkdir();
String fileName = "./output/" + this.getClass().getSimpleName() + "_"
+ Calendar.getInstance().getTimeInMillis() + ".xml";
try (OutputStream stream = new FileOutputStream(new File(fileName))) {
try (OutputStreamWriter out = new OutputStreamWriter(stream, StandardCharsets.UTF_16)) {
out.write(xmlContent);
out.write("\n");
}
} catch (IOException ex) {
System.err.println("Cannot write to file!" + ex.getMessage());
}
}
public static void main(String[] args) throws CreateDocumentConfigurationException {
XmlBuilder xmlBuilder = new XmlBuilder();
Map<String, List<String>> map = MapFactory.mapOf(MapFactory.entry("root", Arrays.asList("element1", "element2", "element3")));
String xmlContent = xmlBuilder.generateXmlContent(map);
xmlBuilder.writeToXmlFile(xmlContent);
}
}
Output after execution will be:
<?xml version="1.0" encoding="UTF-16"?>
<root>
<element1/>
<element2/>
<element3/>
</root>
Here's an algorithm that's easy to implement, assuming that you have a simple result set retrieved from the database, which contains the two columns you mentioned.
Loop through all records first and construct an XML Node object for each XML_NAME name (put the XML Node objects in a List).
Create a HashMap with String keys (XML_NAME name) and XML Node objects as values. Add each XML Node as an entry into this map.
Loop through all records again (only once) and for each XML_NAME - XML_PARENT_NAME pair, look up both XML Node objects in the map. Add the XML Node of the former to the list of child nodes for the latter.
Create a root XML Node. Loop through the list of XML Nodes and add each node which doesn't have a parent to this root node, as a child of the root node.
Convert the root XML Node to String or do whatever you want with it.
I'm using JAXB marshalling to create XML files, and it created successfully, and know i want to display these files using JAXB unMarshalling, here is the code i'm using:
public Object display(String fileName) throws IOException, JAXBException {
XmlStructure object;
File file = new File(fileName);
JAXBContext jaxbContext = JAXBContext.newInstance(XmlStructure.class);
Unmarshaller jaxbUnMarshaller = jaxbContext.createUnmarshaller();
object = (XmlStructure) jaxbUnMarshaller.unmarshal(file);
System.out.println(object.toString());
return object;
}
the previous code gives me that result:
com.nc.inotify.dp.xml.impl.XmlStructure#2916a6bf
and i changed the code with that:
public Object display(String fileName) throws IOException, JAXBException {
XmlStructure object;
File file = new File(fileName);
JAXBContext jaxbContext = JAXBContext.newInstance(XmlStructure.class);
Unmarshaller jaxbMarshaller = jaxbContext.createUnmarshaller();
object = (XmlStructure) jaxbMarshaller.unmarshal(file);
Marshaller jaxbMarshallerz = jaxbContext.createMarshaller();
jaxbMarshallerz.marshal(object, System.out);
return object;
}
but it gives me that result:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><XmlSource/>
and this is the XML file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<XmlSource>
<XmlConf>
<hostName>weather.yahooapis.com</hostName>
<parameters>
<entry>
<key>w</key>
<value>2502265</value>
</entry>
</parameters>
<URLPath>/forecastrss</URLPath>
<urlProtocol>http</urlProtocol>
</XmlConf>
<XmlConf>
<hostName>weather.yahooapis.com</hostName>
<parameters>
<entry>
<key>w</key>
<value>2553822</value>
</entry>
</parameters>
<URLPath>/forecastrss</URLPath>
<urlProtocol>http</urlProtocol>
</XmlConf>
</XmlSource>
Update
*NOTE*: i'm using more than one class in the marshaling process in order to get that form
The marshaling method:
public void add(String fileName) throws IOException, JAXBException,
ParserConfigurationException, SAXException, TransformerException {
this.fileName = fileName;
File temp = new File(tempName);
JAXBContext jaxbContext = JAXBContext.newInstance(XmlConfList.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
File source = new File(fileName);
if (source.exists()) {
jaxbMarshaller.marshal(object, temp);
MergeXml merge = new MergeXml();
merge.mergeXML(true, fileName, tempName, mainTag);
} else {
XmlStructure struct = new XmlStructure();
jaxbMarshaller.marshal(struct, source);
jaxbMarshaller.marshal(object, temp);
MergeXml merge = new MergeXml();
merge.mergeXML(true, fileName, tempName, mainTag);
}
temp.delete();
}
The MergeXml class:
public class MergeXml {
private static final String YES = "yes";
private static final String generalTag = "*";
/**
* This method used to merge XML old and new files together
*/
public void mergeXML(boolean condition, String fileName, String tempName, String mainTag)
throws ParserConfigurationException, SAXException, IOException,
TransformerException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
Document doc = null;
Document doc2 = null;
db = dbf.newDocumentBuilder();
doc = db.parse(new File(fileName));
doc2 = db.parse(new File(tempName));
NodeList elements = doc.getElementsByTagName(mainTag);
if (condition == true) {
NodeList nodeList = doc2.getElementsByTagName(generalTag);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
Node childNode = doc.adoptNode(node);
elements.item(0).appendChild(childNode);
}
}
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, YES);
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
BufferedWriter output = new BufferedWriter(new FileWriter(fileName));
String xmlOutput = result.getWriter().toString();
output.write(xmlOutput);
output.close();
}
}
The XmlStructure class:
#XmlRootElement(name = "XmlSource")
public class XmlStructure{
}
The XmlConf class:
#XmlRootElement(name = "XmlConf")
public class XmlConf extends XmlStructure {
private String URLProtocol;
private List<String> path = new ArrayList<String>();
private String urlp;
private Map<String, String> parameters;
private String host;
/**
* This method used to retrieve the specified URL protocol
* #return {#code String}
*/
public String getUrlProtocol() {
return URLProtocol;
}
/**
* This method used to store the URL protocol as String if the URL is a valid one
* #param URL Protocol
*
*/
#XmlElement
public void setUrlProtocol(String URLProtocol) {
this.URLProtocol = URLProtocol;
}
/**
* This method used to retrieve all the paths selected
* by the user in order to save
* #return {#code List<String>}
*/
#XmlElement
public List<String> getPath() {
return path;
}
/**
* This method used to store a new path added by the user
* #param path
*
*/
public void setPath(String path) {
this.path.add(path);
}
/**
* This method used to set the path of the specified URL
* #param urlp
*
*/
#XmlElement(name = "URLPath")
public void setUrlPath(String urlp) {
this.urlp = urlp;
}
/**
* This method used to retrieve the path of the specified URL
* #return {#code String}
*/
public String getUrlPath() {
return urlp;
}
/**
* This method used to set the parameters of the specified URL
* #param parameters
*
*/
#XmlElementWrapper
public void setParameters(Map<String, String> parameters) {
this.parameters = parameters;
}
/**
* This method used to retrieve the parameters
* of the specified URL
* #return {#code Map<String, String>}
*/
public Map<String, String> getParameters() {
return parameters;
}
/**
* This method used to set the host name of the specified URL
* #param host
*
*/
public void setHostName(String host) {
this.host = host;
}
/**
* This method used to retrieve the host name of the
* specified URL
* #return {#code String}
*/
public String getHostName() {
return host;
}
}
The XmlConfList class:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class XmlConfList {
#XmlElementWrapper(name = "XmlSource")
#XmlElement(name = "XmlConf")
private List<XmlConf> list = null;
public List<XmlConf> getList() {
if(this.list == null)
this.list = new ArrayList<>();
return this.list;
}
}
I use Simple XML (simple-xml-2.6.2.jar) to parse xml file like:
<?xml version="1.0" encoding="UTF-8" ?>
<orderList>
<order id="1">
<name>NAME1</name>
</order>
<order id="2">
<name>NAME2</name>
</order>
</orderList>
The root Element contains subElements.
I wanna it be ArrayList, How to do it?
Here's a possible solution, hope it helps you:
Annotations of Order class:
#Root(name="order")
public class Order
{
#Attribute(name="id", required=true)
private int id;
#Element(name="name", required=true)
private String name;
public Order(int id, String name)
{
this.id = id;
this.name = name;
}
public Order() { }
// Getter / Setter
}
Example class, containing the list:
#Root(name="elementList")
public class Example
{
#ElementList(required=true, inline=true)
private List<Order> list = new ArrayList<>();
// ...
}
And here's some code for reading your code:
Serializer ser = new Persister();
Example example = ser.read(Example.class, file); // file = your xml file
// 'list' now contains all your Orders
List is an interface, ArrayList is one of its implementation, like:
List<Order> l = new ArrayList<Order>()
So if you have a List , you basically have what you want.
If I've interpreted your question correctly, you want a list of orders. I've not tested this for your setup but this works for me for a similar xml structure (assumes you have a custom class called Order):
List<Order> orders = new ArrayList<Order>();
XMLDOMParser parser = new XMLDOMParser();
AssetManager manager = context.getAssets();
InputStream stream;
try {
stream = manager.open("test.xml"); //need full path to your file here - mine is stored in assets folder
Document doc = parser.getDocument(stream);
}catch(IOException ex){
System.out.printf("Error reading xml file %s\n", ex.getMessage());
}
NodeList nodeList = doc.getElementsByTagName("order");
for (int i = 0; i < nodeList.getLength(); i++) {
Element e = (Element) nodeList.item(i); //each order item
Node order=nodeList.item(i);
subList = order.getFirstChild(); //get the name child node
orders.add(order);
}
//XMLDOMParser Class
public class XMLDOMParser {
//Returns the entire XML document
public Document getDocument(InputStream inputStream) {
Document document = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = factory.newDocumentBuilder();
InputSource inputSource = new InputSource(inputStream);
document = db.parse(inputSource);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
return document;
}
/*
* I take a XML element and the tag name, look for the tag and get
* the text content i.e for <employee><name>Kumar</name></employee>
* XML snippet if the Element points to employee node and tagName
* is name I will return Kumar. Calls the private method
* getTextNodeValue(node) which returns the text value, say in our
* example Kumar. */
public String getValue(Element item, String name) {
NodeList nodes = item.getElementsByTagName(name);
return this.getTextNodeValue(nodes.item(0));
}
private final String getTextNodeValue(Node node) {
Node child;
if (node != null) {
if (node.hasChildNodes()) {
child = node.getFirstChild();
while(child != null) {
if (child.getNodeType() == Node.TEXT_NODE) {
return child.getNodeValue();
}
child = child.getNextSibling();
}
}
}
return "";
}
}
I have to read and write to and from an XML file. What is the easiest way to read and write XML files using Java?
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;
#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();
}
}
}
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 you
get what you need.
Some example code:
http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/
The answers only cover DOM / SAX and a copy paste implementation of a JAXB example.
However, one big area of when you are using XML is missing. In many projects / programs there is a need to store / retrieve some basic data structures. Your program has already a classes for your nice and shiny business objects / data structures, you just want a comfortable way to convert this data to a XML structure so you can do more magic on it (store, load, send, manipulate with XSLT).
This is where XStream shines. You simply annotate the classes holding your data, or if you do not want to change those classes, you configure a XStream instance for marshalling (objects -> xml) or unmarshalling (xml -> objects).
Internally XStream uses reflection, the readObject and readResolve methods of standard Java object serialization.
You get a good and speedy tutorial here:
To give a short overview of how it works, I also provide some sample code which marshalls and unmarshalls a data structure.
The marshalling / unmarshalling happens all in the main method, the rest is just code to generate some test objects and populate some data to them.
It is super simple to configure the xStream instance and marshalling / unmarshalling is done with one line of code each.
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;
}
}
}
Ok, already having DOM, JaxB and XStream in the list of answers, there is still a complete different way to read and write XML: Data projection You can decouple the XML structure and the Java structure by using a library that provides read and writeable views to the XML Data as Java interfaces. From the tutorials:
Given some real world XML:
<weatherdata>
<weather
...
degreetype="F"
lat="50.5520210266113" lon="6.24060010910034"
searchlocation="Monschau, Stadt Aachen, NW, Germany"
... >
<current ... skytext="Clear" temperature="46"/>
</weather>
</weatherdata>
With data projection you can define a projection interface:
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();
}
And use instances of this interface just like 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());
}
This works even for creating XML, the XPath expressions can be writable.
SAX parser is working differently with a DOM parser, it neither load any XML document into memory nor create any object representation of the XML document. Instead, the SAX parser use callback function org.xml.sax.helpers.DefaultHandler to informs clients of the XML document structure.
SAX Parser is faster and uses less memory than DOM parser.
See following SAX callback methods :
startDocument() and endDocument() – Method called at the start and end of an XML document.
startElement() and endElement() – Method called at the start and end of a document element.
characters() – Method called with the text contents in between the start and end tags of an XML document element.
XML file
Create a simple XML file.
<?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>
XML parser:
Java file Use SAX parser to parse the XML file.
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();
}
}
}
Result
Start Element :company
Start Element :staff
Start Element :firstname
First Name : yong
End Element :firstname
Start Element :lastname
Last Name : mook kim
End Element :lastname
Start Element :nickname
Nick Name : mkyong
End Element :nickname
and so on...
Source(MyKong) - http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/