0

I have the correct output coming out of my parser for the xml file, but am not able to add the object correctly to my array. I put a demo on runnable...

<?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>

Following this simple SAX tutorial I have parsed the employee xml and successfully added it to a list, however, when I create my Employee.class and try and set the First,Last,Nick and Salary to the emp object:

emp.setFirstName(fname);

I am unable to get the correct results in my object array:

Employee emp = new Employee();
ArrayList<Employee> empList = new ArrayList<Employee>(); //ERROR returns 21 items
ArrayList<String> testList = new ArrayList<String>(); //CORRECT returns 8 items

public void characters(char ch[], int start, int length) throws SAXException {

        if (bfname) {

            fname = new String(ch, start, length);
            System.out.println("First Name : " + fname);
            emp.setFirstName(fname);
            testList.add(fname);
            bfname = false;
        }

        if (blname) {

            lname = new String(ch, start, length);
            System.out.println("Last Name : " + lname);
            emp.setLastName(lname);
            testList.add(lname);
            blname = false;
        }

        if (bnname) {

            nname = new String(ch, start, length);
            System.out.println("Nick Name : "+ nname);
            emp.setNickName(nname);
            testList.add(nname);
            bnname = false;
        }

        if (bsalary) {

            salary = new String(ch, start, length);
            System.out.println("Salary : " + salary);
            emp.setSalary(salary);
            testList.add(salary);
            bsalary = false;
        }
    empList.add(emp);
    }

The testList will show 8 items, the empList will return 21 items which when read out to the screen is 21 lines of the last entry in the xml document.

What am I doing incorrectly here?

SOLVED::: Thanks @zakimak:

if (bfname) {
**emp = new Employee();**
            fname = new String(ch, start, length);
            System.out.println("First Name : " + fname);
            emp.setFirstName(fname);
            testList.add(fname);
            bfname = false;

        }

        if (blname) {

            lname = new String(ch, start, length);
            System.out.println("Last Name : " + lname);
            emp.setLastName(lname);
            testList.add(lname);
            blname = false;

        }

        if (bnname) {

            nname = new String(ch, start, length);
            System.out.println("Nick Name : "+ nname);
            emp.setNickName(nname);
            testList.add(nname);
            bnname = false;

        }

        if (bsalary) {

            salary = new String(ch, start, length);
            System.out.println("Salary : " + salary);
            emp.setSalary(salary);
            testList.add(salary);
            bsalary = false;
            **empList.add(emp)**;
        }
2
  • I would add the XML you're parsing from to the question. Commented Jan 9, 2015 at 15:12
  • added. check the runnable link for a working demo Commented Jan 9, 2015 at 15:20

2 Answers 2

1

Here is a solution. Every time you start with the bfname tag, you create a new Employee and once the bsalary is received, you add it to the list. The idea is when you start with the first tag(bfname) we can assume we are reading a new Employee, so we create a fresh object. And lastly when we reach the last tag(bsalary) we know that this is the final tag and should add it to the list. The problem with your code was that it was adding the Employee object no matter what tag was read. You should define granular start and end point when parsing XML data for a bean.

        if (bfname) {
            emp = new Employee();
            fname = new String(ch, start, length);
            System.out.println("First Name : " + fname);
            emp.setFirstName(fname);
            testList.add(fname);
            bfname = false;
        }

.....

     if (bsalary) {

        salary = new String(ch, start, length);
        System.out.println("Salary : " + salary);
        emp.setSalary(salary);
        testList.add(salary);
        bsalary = false;
        empList.add(emp);
    }
Sign up to request clarification or add additional context in comments.

3 Comments

This makes sense, almost :), but if I added empList.add(emp) to the bsalary, I still only get an array with the information of the last entry two times.
Thanks! That was trick. Do you see any issues besides NULL results with this?
I don't see any as long as the XML design is maintained. It should work with empty tags too. But make sure that the firstname and salary tags are at least there so that we know where the start is and the end is. A better solution is to make new Employee when "staff" tag is read in (characters function) and the object is added to list when "endElement" is reached for "staff". Either way our code will fail if XML is malformed.
0
public void endElement(String uri, String localName,
    String qName) throws SAXException {

    //System.out.println("End Element :" + qName);
    if (qName.equalsIgnoreCase("STAFF")) {
      empList.add(emp);
      emp = new Employee();
    }

}

And remove

empList.add(emp);

from characters function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.