Search code examples
javastax

Issue with STAX parsing in Java


I have an XML file as follows:

<?xml version="1.0" encoding="UTF-8"?>
<top>
<dist id="1">
<emp name="gaara" age="22" location="konoha"/>
<emp name="vegeta" age="44" location="namek"/>
<assitant name="nappa" age="64" location="namek"/>
</dist>

<dist id="2">
<emp name="naruto" age="20" location="konoha"/>
<emp name="lei" age="21" location="sand"/>
<assitant name="gohan" age="25" location="island"/>
</dist>

</top>

The expected result is as follows:

Required O/P
1 | gaara | 22 | konoha
1 | vegeta | 44 | namek
2 | naruto | 20 | konoha
2 | lei | 21 |sand

Can anyone explain how can I do the same. And one thing is the output should not contain assistant element data.

I would have posted the code but since the elements appear more than once the code I have is not working.

EDIT I am posting the code :

1) The class containing the main

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
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;


public class loadNwccData {
  public static void main(String[] args) throws XMLStreamException, FileNotFoundException {
    List<Employee> empList = null;
    Employee currEmp = null;
    XMLInputFactory factory = XMLInputFactory.newInstance();


    InputStream inputStream= new FileInputStream("C:\\Documents and Settings\\samp\\Desktop\\sample.xml");

    XMLStreamReader reader = 
        factory.createXMLStreamReader(inputStream);

    while(reader.hasNext()){
      int event = reader.next();

      switch(event){
        case XMLStreamConstants.START_ELEMENT: 
          if ("dist".equals(reader.getLocalName())){
            currEmp = new Employee();
            currEmp.id = reader.getAttributeValue(null, "id");
          }
          else if ("emp".equals(reader.getLocalName())){

              currEmp.name = reader.getAttributeValue(null, "name");
              currEmp.age = reader.getAttributeValue(null, "age");
              currEmp.location = reader.getAttributeValue(null, "location");
            }
          if("top".equals(reader.getLocalName())){
            empList = new ArrayList<Employee>();
          }
          break;


            case XMLStreamConstants.END_ELEMENT:
            Cloumns value = Cloumns.valueOf(reader.getLocalName());
          switch(value){
            case emp:
              empList.add(currEmp);
              break;

          }
          break;

        case XMLStreamConstants.START_DOCUMENT:
          empList = new ArrayList<Employee>();
          break;
      }

    }

    //Print the employee list populated from XML
    for ( Employee emp : empList){
      System.out.println(emp);
    }

  }
}

class Employee{
  String id;
  String name;
  String age;
  String location;

  @Override
  public String toString(){
    return id +" | " +name +" | "+age +" | "+location;
  }
}

2) The eenum file

public enum Cloumns {emp,assitant,dist,top};

3) The O/P I'm getting:

1 | vegeta | 44 | namek
1 | vegeta | 44 | namek
2 | lei | 21 | sand
2 | lei | 21 | sand

Can anyone please point out what is the issue here as the values are repeating.


Solution

  • The trouble is you create Employee record for dist elements.

    if ("dist".equals(reader.getLocalName())){
                currEmp = new Employee();
                currEmp.id = reader.getAttributeValue(null, "id");
              }
    

    This is followed my multiple employee definition. Effectively making the last element data into Employee record.

    I would store the id into a variable, say currentDistID and use it with Employee. The employee record should be created for each employee element.

    code

      public static void main(String[] args) throws XMLStreamException, FileNotFoundException {
        List<Employee> empList = null;
        Employee currEmp = null;
    
        XMLInputFactory factory = XMLInputFactory.newInstance();
        String currentDistID=null;
    
        InputStream inputStream= new FileInputStream("c:\\sample.xml");
    
        XMLStreamReader reader =
                factory.createXMLStreamReader(inputStream);
    
        while(reader.hasNext()){
            int event = reader.next();
    
            switch(event){
                case XMLStreamConstants.START_ELEMENT:
                    if ("dist".equals(reader.getLocalName())){
                        //all subsequent employees share this.
                        currentDistID = reader.getAttributeValue(null, "id");
                    }
                    else if ("emp".equals(reader.getLocalName())){
                        currEmp = new Employee();
                        currEmp.id=currentDistID;
                        currEmp.name = reader.getAttributeValue(null, "name");
                        currEmp.age = reader.getAttributeValue(null, "age");
                        currEmp.location = reader.getAttributeValue(null, "location");
                    }
                    if("top".equals(reader.getLocalName())){
                        empList = new ArrayList<Employee>();
                    }
                    break;
    
    
                case XMLStreamConstants.END_ELEMENT:
                    Cloumns value = Cloumns.valueOf(reader.getLocalName());
                    switch(value){
                        case emp:
                            empList.add(currEmp);
                            break;
    
                    }
                    break;
    
                case XMLStreamConstants.START_DOCUMENT:
                    //empList = new ArrayList<Employee>();
                    break;
            }
    
        }
    
        //Print the employee list populated from XML
        for ( Employee emp : empList){
            System.out.println(emp);
        }
    
    }