XML Processing in Java-using StAX

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.




1
Bijoy
10 A

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.




Bijoy
10
A

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.




1
Bijoy
10 A

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.




1
Bijoy

 

See also :

XML Processing in Java

DOM interface

SAX interface

JAXB