Prabha
Prabha

Reputation: 705

How to write Data into XML file using JAXB?

I am using eclipse-link, and I am retrieving data from table and trying to store the retrieved data into XML file using JAXB. While writing into XML file last record only saved in that file.

Here User is My POJO class have Two fields

@XmlRootElement
public class User implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;

private  String name;

@XmlAttribute
public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}
@XmlElement
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

 public User()
{

}
}

Below is My code:

public class ObjectToXml {
private static int startingIndex = 0;
private static int maxIndex= 10;

public static void main(String[] args) {

    EntityManager entityManager = EntityManagerUtil.getEmf()
            .createEntityManager();
    Query query = entityManager.createQuery("Select u from User u");

    System.out.println("Total Number of Records"
            + query.getResultList().size());
    try {

        JAXBContext contextObj = JAXBContext.newInstance(User.class);

        Marshaller marshallerObj = contextObj.createMarshaller();
        marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);          

        query.setFirstResult(startingIndex );
        query.setMaxResults(maxIndex);
        List<User> user = query.getResultList();

        Iterator iterator = user.iterator();
        while (iterator.hasNext()) {
            User student = (User) iterator.next();  
        MarshallerObj.marshal(student, new FileOutputStream("User.xml"));

        }

    } catch (Exception e) {
        e.printStackTrace();
    }

    finally {
        entityManager.close();

    }
}
}

Here i am getting 10 records.But while storing last Record only saved in XML

My Result :

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<user id="10">
<name>prabha</name> 
</user> 

Upvotes: 2

Views: 8756

Answers (4)

Sanket Meghani
Sanket Meghani

Reputation: 905

You will need to use @XmlElements annotation.

Marshaller.marshal() simply converts the object into byte stream and writes into output stream. Hence it will override the existing data in ouputstream. In your case, since marshallerObj.marshal(student, new FileOutputStream("User.xml")); is inside a loop, the final file would always contain the last object in the list. I.e in the first iteration it will write first object to the file, in second iteration it will overwrite the file with second object, in third iteration it will overwrite the file with third object and so on.

To marshal a list of objects, one of the solution is to create a container object which will maintain a list of all users/students and then marshal the container object.

Refer to link for similar question.

In your case the container class should look something like:

@XmlRootElement(name = "Users")
public class Users
{
    private List<User> users = new ArrayList<User>();

    @XmlElements(value = {@XmlElement(name = "User", type = User.class)})
    @XmlElementWrapper
    public List<User> getUsers() {
        return users;
    }

    public void addUser(User user) {
        users.add(user);
    }
}

And the code to marshal the Users:

Users users = new Users();

List<User> usersList = query.getResultList();

for(User user : usersList) {
    users.addUser(user);
}

marshallerObj.marshal(users, new FileOutputStream("User.xml"));

Upvotes: 1

Sanoop
Sanoop

Reputation: 1022

Since you are creating xml file for each User object, the objects will be keep on replacing when the program is taking an new User from DB
So create a POJO class Users with List of User as an attribute,

public class Users 
{
//Users grouping
private List<User> user;

public void setUser(List<ProductInfo> userInfo) 
{
    this.user = userInfo;
}

@XmlElement(name="user")
public List<User> getUser() {
    return user;
}

}

Then in the code section create instance of JAXBContext for the class Users, like mentioned below

 JAXBContext contextObj = JAXBContext.newInstance(Users.class);

Now modify the while loop to set all user's information into Users object, and marshar the Users object than marshaling the User object.

Users users = new Users();
while (iterator.hasNext()) {
      User student = (User) iterator.next();  
      users.setUser(student);
}
MarshallerObj.marshal(users, new FileOutputStream("User.xml"));

Upvotes: 1

Sanjeev
Sanjeev

Reputation: 9946

Because MarshallerObj.marshal(student, new FileOutputStream("User.xml")); creating new file o/p stream everytime and that clears prev contents. create this instance of o/p stream out of your while loop. that should help.

Upvotes: 2

Smutje
Smutje

Reputation: 18123

Perhaps you should keep one single FileOutputStream and marshall continuously into it instead of creating a new one on every iteration.

Upvotes: 1

Related Questions