Java StAX Cursor Based API Read XML Example

Filed Under: Java

Java StAX API provides two XML processing API – cursor based and iterator based. Earlier we saw examples of iterator based API to read XML file and write XML file. Here we will learn how to use cursor based API to read XML file.

When we use StAX XML Parser, we need to create XMLInputFactory to read XML file. Then we can chose cursor based API by creating XMLStreamReader object to read file. XMLStreamReader next() method is used to get the next parsing event and it returns the int value depending on the event type. Common event types are Start Document, Start Element, Characters, End Element and End Document. XMLStreamConstants contains int constants that can be used to process events based on it’s type.

For this tutorial, we have below xml file that is list of Employee element.


<?xml version="1.0" encoding="UTF-8"?>
<Employees>
	<Employee id="1">
		<age>29</age>
		<name>Pankaj</name>
		<gender>Male</gender>
		<role>Java Developer</role>
	</Employee>
	<Employee id="2">
		<age>35</age>
		<name>Lisa</name>
		<gender>Female</gender>
		<role>CEO</role>
	</Employee>
	<Employee id="3">
		<age>40</age>
		<name>Tom</name>
		<gender>Male</gender>
		<role>Manager</role>
	</Employee>
	<Employee id="4">
		<age>25</age>
		<name>Meghna</name>
		<gender>Female</gender>
		<role>Manager</role>
	</Employee>
</Employees>

We have Employee class to represent the Employee element.


package com.journaldev.xml;

public class Employee {
    private int id;
    private String name;
    private String gender;
    private int age;
    private String role;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getRole() {
        return role;
    }
    public void setRole(String role) {
        this.role = role;
    }
    
    @Override
    public String toString() {
        return "Employee:: ID="+this.id+" Name=" + this.name + " Age=" + this.age + " Gender=" + this.gender +
                " Role=" + this.role;
    }
    
}

Here is the class where we are using StAX XMLStreamReader to read the xml file to list of Employee object.


package com.journaldev.xml.stax;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import com.journaldev.xml.Employee;

public class StaxXMLStreamReader {
    
    private static boolean bName;
    private static boolean bAge;
    private static boolean bGender;
    private static boolean bRole;

    public static void main(String[] args) {
        String fileName = "/Users/pankaj/employees.xml";
        List<Employee> empList = parseXML(fileName);
        for(Employee emp : empList){
            System.out.println(emp.toString());
        }
    }

    private static List<Employee> parseXML(String fileName) {
        List<Employee> empList = new ArrayList<>();
        Employee emp = null;
        XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
        try {
            XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new FileInputStream(fileName));
            int event = xmlStreamReader.getEventType();
            while(true){
                switch(event) {
                case XMLStreamConstants.START_ELEMENT:
                    if(xmlStreamReader.getLocalName().equals("Employee")){
                        emp = new Employee();
                        emp.setId(Integer.parseInt(xmlStreamReader.getAttributeValue(0)));
                    }else if(xmlStreamReader.getLocalName().equals("name")){
                        bName=true;
                    }else if(xmlStreamReader.getLocalName().equals("age")){
                        bAge=true;
                    }else if(xmlStreamReader.getLocalName().equals("role")){
                        bRole=true;
                    }else if(xmlStreamReader.getLocalName().equals("gender")){
                        bGender=true;
                    }
                    break;
                case XMLStreamConstants.CHARACTERS:
                    if(bName){
                        emp.setName(xmlStreamReader.getText());
                        bName=false;
                    }else if(bAge){
                        emp.setAge(Integer.parseInt(xmlStreamReader.getText()));
                        bAge=false;
                    }else if(bGender){
                        emp.setGender(xmlStreamReader.getText());
                        bGender=false;
                    }else if(bRole){
                        emp.setRole(xmlStreamReader.getText());
                        bRole=false;
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    if(xmlStreamReader.getLocalName().equals("Employee")){
                        empList.add(emp);
                    }
                    break;
                }
                if (!xmlStreamReader.hasNext())
                    break;

              event = xmlStreamReader.next();
            }
            
        } catch (FileNotFoundException | XMLStreamException e) {
            e.printStackTrace();
        }
        return empList;
    }
}

When we execute above program, we get following output in console.


Employee:: ID=1 Name=Pankaj Age=29 Gender=Male Role=Java Developer
Employee:: ID=2 Name=Lisa Age=35 Gender=Female Role=CEO
Employee:: ID=3 Name=Tom Age=40 Gender=Male Role=Manager
Employee:: ID=4 Name=Meghna Age=25 Gender=Female Role=Manager

Comments

  1. Ruben Garcia says:

    Is there a more efficient way other than if else if to implement the logic inside your parseXML()

  2. Praveen says:

    Simple and superb, thanks Pankaj for the nice example.

  3. 32U says:

    This was excellent. I was struggling for days but this is a very elegant way to handle reading xml into an object. Good work.

  4. Ajas says:

    Thanks for the post,it is very helpful.
    I want to retrieve complete xml file text as csv file which contains documents,sub documents,etc..
    I tried your code for my xml it is retrieving only the last stream text.
    Can you please help me on this.

    Thanks,
    Aijas

  5. ???????? ??? says:

    It? actually a nice and useful piece of information. I? glad that you shared this useful information with us. Please keep us informed like this. Thanks for sharing.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages