So far we discussed about DOM parser and SAX parser. DOM parser allows random access to any element in the XML document.But performance is slower .Because the entire content is loading to memory first , and this idea is not at all feasible in applications handling XML files of very large size.SAX avoids this problem.It uses event listeners and call back methods to parse XML documents.But this may get complicated if the XML document is complicated . The complete document is not loading in to memory.A StAX Parser is considered as a median between DOM and SAX.
Overview to StAX
StAX or Streaming API for XML stands as a median of DOM and SAX. It is specified by JSR-173 of Java Community Process .In StAX ,a point called Cursor is creating, then the application moves the cursor forward and pulls the data from the document.The StAX has two APIs
a)The Cursor API
b)The event-iterator API
Lets discuss these two APIs in detail .
a)Cursor API
The Cursor API provides options for parsing XML files as well as generating XML files.The important interfaces in Cursor API are XMLStreamReader and XMLStreamWriter.The XMLStreamReader interface is using to parse an XML file.S imilarly ,the XMLStreamWriter interface is using in generating an XML file. Okay , lets see the XML processing with Cursor API with suitable examples.
Parsing XML file using Cursor API
As we discussed , the cursor API is having XMLStreamReader interface and which is using in parsing an XML document.In this example , we are taking an XML file student.xml as input.
Now lets see the Java code to parse the XML document.The steps involved are :
1)Create XMLInputFactory object
2)Create XMLStreamReader object for the input XML.
3)Iterate the XMLStreamReader object and identify the various elements in the document
4)After reading the entire document , close the XMLStreamReader object.
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class CursorAPIParser {
public CursorAPIParser() {
}
public void parseAndDisplay() {
try {
XMLInputFactory factory = XMLInputFactory.newFactory();
XMLStreamReader reader = factory.createXMLStreamReader(new FileReader("C:\\Users\\My PC\\Projects\\Sample\\files\\student.xml"));
//Now iteration
while (reader.hasNext()) {
parseEvent(reader);
reader.next();
}
reader.close();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void parseEvent(XMLStreamReader reader) {
switch (reader.getEventType()) {
case XMLStreamConstants.START_DOCUMENT:
System.out.println("Start of document");
break;
case XMLStreamConstants.START_ELEMENT:
System.out.println("Start element = " + reader.getLocalName());
break;
case XMLStreamConstants.CHARACTERS:
int beginIndex = reader.getTextStart();
int endIndex = reader.getTextLength();
String value = new String(reader.getTextCharacters(),
beginIndex,
endIndex).trim();
if (!value.equalsIgnoreCase(""))
System.out.println("Value = " + value);
break;
case XMLStreamConstants.END_ELEMENT:
System.out.println("End element = " + reader.getLocalName());
break;
case XMLStreamConstants.COMMENT:
if (reader.hasText())
System.out.print(reader.getText());
break;
}
}
public static void main(String[] args) {
CursorAPIParser parser = new CursorAPIParser();
parser.parseAndDisplay();
}
}
While creating the XMLStreamReader object , the FileInputStream object of the input XML file is passing as argument.
Output
Start of document
Start element = school
Start element = student
Start element = id
Value = 1
End element = id
Start element = name
Value = Bijoy
End element = name
Start element = class
Value = 10
End element = class
Start element = division
Value = A
End element = division
End element = student
End element = school
Generating XML using Cursor API
Now let us see how to generate XML file using Cursor API.The cursor API is having an interface called XMLStreamWriter.It is using while generating XML file.
The steps in Generating XML document are:
1)Create and XMLOutputFactory instance.
2)Create XMLStreamWriter instance with FileOutputStream of output file as argument.
3)Generate the XML elements from start of document to end of document using XMLStreamWriter object.
4)Close XMLStreamWriter object.
Now let us see a sample code which generates a student1.xml in a specified path.
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class CursorAPIGenerator {
public CursorAPIGenerator() {
}
public void generateXML() {
try {
XMLOutputFactory factory = XMLOutputFactory.newInstance();
XMLStreamWriter writer = factory.createXMLStreamWriter(new FileOutputStream("C:\\Users\\My PC\\Projects\\Sample\\files\\student1.xml"));
writer.writeStartDocument();
writer.writeCharacters("\n");
writer.writeStartElement("school");
writer.writeCharacters("\n");
writer.writeStartElement("student");
writer.writeAttribute("id", "1");
writer.writeCharacters("\n");
writer.writeStartElement("", "name", "");
writer.writeCharacters("Bijoy");
writer.writeEndElement();
writer.writeCharacters("\n");
writer.writeStartElement("", "class", "");
writer.writeCharacters("10");
writer.writeEndElement();
writer.writeCharacters("\n");
writer.writeStartElement("", "Division", "");
writer.writeCharacters("A");
writer.writeEndElement();
writer.writeCharacters("\n");
writer.writeEndElement();
writer.writeCharacters("\n");
writer.writeEndElement();
writer.writeCharacters("\n");
writer.writeEndDocument();
writer.close();
System.out.println("Finished");
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
CursorAPIGenerator generator = new CursorAPIGenerator();
generator.generateXML();
}
}
Now please check the file path of FileOutputStream for the student1.xml.
b)Event-Iterator API
The event-iterator API is built on top of Cursor API.The cursor API is the popular one when comparing with Event-Iterator API.Event-Iterator API provides facilities for parsing and generating XML files.The XMLEventReader and XMLEventWriter are the important interfaces .XMLEventReader is useful when parsing an XML document.Similarly XMLEventWriter is useful while generating XML document.
Parsing XML file using event-iterator API
The steps in parsing an XML file using event iterator API are:
1)Create XMLInputFactory object .
2)Create XMLEventReader object for the input XML file.
3)Iterate the XMLEventReader for the XMLEvent object till the end.
4)Parse the XMLEvent .
Now let us see out input student.xml.
Now lets see the java code for parsing an XML document with event-iterator API in StAX.
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class EventIteratorParser {
public EventIteratorParser() {
}
public void parseDocument() {
try {
XMLInputFactory factory = XMLInputFactory.newFactory();
XMLEventReader reader = factory.createXMLEventReader(new FileReader("C:\\Users\\My PC\\Projects\\Sample\\files\\student.xml"));
while (reader.hasNext()) {
XMLEvent event = reader.nextEvent();
parseEvent(event);
}
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void parseEvent(XMLEvent event) {
switch (event.getEventType()) {
case XMLEvent.START_DOCUMENT:
System.out.println("Start document");
break;
case XMLEvent.START_ELEMENT:
System.out.println("Start element : " + event.asStartElement().getName());
break;
case XMLEvent.CHARACTERS:
String value = event.asCharacters().toString().trim();
if (!value.equalsIgnoreCase(""))
System.out.println("Value = " + value);
break;
case XMLEvent.END_ELEMENT:
System.out.println("End element : " + event.asEndElement().getName());
break;
case XMLEvent.END_DOCUMENT:
System.out.println("End document");
break;
}
}
public static void main(String[] args) {
EventIteratorParser parser = new EventIteratorParser();
parser.parseDocument();
}
}
Now we can verify the output.
Output
Start document
Start element : school
Start element : student
Start element : id
Value = 1
End element : id
Start element : name
Value = Bijoy
End element : name
Start element : class
Value = 10
End element : class
Start element : division
Value = A
End element : division
End element : student
End element : school
End document
Generating XML using Event-Iterator API
The XMLEventWriter interface is using to generate XML document. The steps are :
1)Create XMLOutputFactory instance
2)Create XMLEventWriter object .
3)Create XMLEventFactory object for generating various XMLEvent objects (like StartDocument , EndDocument ,StartElement ,etc..)
4)Generate various XML events and write those events to output file using XMLEventWriter object.
5)Close the XmLWriter object.
Now let us see the Java code for generating XML file using event-iterator API of Stax.
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.*;
import java.io.FileOutputStream;
import java.io.IOException;
public class EventIteratorGenerator {
public EventIteratorGenerator() {
}
public void generateXML() {
try {
FileOutputStream outputStream = new FileOutputStream("C:\\Users\\My PC\\IdeaProjects\\Sample\\files\\student1.xml");
XMLOutputFactory factory = XMLOutputFactory.newInstance();
XMLEventWriter writer = factory.createXMLEventWriter(outputStream);
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
StartDocument startDocument = eventFactory.createStartDocument();
writer.add(startDocument);
XMLEvent newLine = eventFactory.createDTD("\n");
writer.add(newLine);
StartElement school = eventFactory.createStartElement("", "", "school");
writer.add(school);
writer.add(newLine);
StartElement student = eventFactory.createStartElement("", "", "student");
writer.add(student);
writer.add(newLine);
StartElement id = eventFactory.createStartElement("", "", "id");
writer.add(id);
Characters idValue = eventFactory.createCharacters("1");
writer.add(idValue);
writer.add(eventFactory.createEndElement("", "", "id"));
writer.add(newLine);
StartElement name = eventFactory.createStartElement("", "", "name");
writer.add(name);
Characters nameValue = eventFactory.createCharacters("Bijoy");
writer.add(nameValue);
writer.add(eventFactory.createEndElement("", "", "name"));
writer.add(newLine);
writer.add(eventFactory.createEndElement("", "", "student"));
writer.add(newLine);
writer.add(eventFactory.createEndElement("", "", "school"));
writer.add(newLine);
EndDocument endDocument = eventFactory.createEndDocument();
writer.add(endDocument);
writer.flush();
writer.close();
outputStream.close();
System.out.println("Finished");
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
EventIteratorGenerator generator = new EventIteratorGenerator();
generator.generateXML();
}
}
Output student1.xml is shown below.
See also :