如何使用JAXB将数据写入XML文件?

时间:2014-02-13 10:33:32

标签: java xml jpa jaxb eclipselink

我正在使用eclipse-link,我正在从表中检索数据并尝试使用JAXB将检索到的数据存储到XML文件中。写入XML文件时,最后一条记录只保存在该文件中。

这里用户是我的POJO类有两个字段

@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()
{

}
}

以下是我的代码:

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();

    }
}
}

这里我得到10条记录。但是存储最后一条记录只保存在XML中

我的结果:

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

4 个答案:

答案 0 :(得分:1)

也许你应该保留一个FileOutputStream并连续编入其中,而不是每次迭代都创建一个新的。{/ p>

答案 1 :(得分:1)

因为MarshallerObj.marshal(student, new FileOutputStream("User.xml"));每次创建新文件o / p流并清除prev内容。从while循环中创建此o / p流实例。应该有所帮助。

答案 2 :(得分:1)

由于您要为每个用户对象创建xml文件,因此当程序从数据库中获取新用户时,对象将继续替换 因此,创建一个POJO类用户,其中包含用户列表作为属性,

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;
}

}

然后在代码部分为类用户创建 JAXBContext 的实例,如下所述

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

现在修改while循环以将所有用户的信息设置为 Users 对象,并 marshar Users对象,而不是编组用户对象。< / p>

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

答案 3 :(得分:1)

您需要使用@XmlElements注释。

Marshaller.marshal()只是将对象转换为字节流并写入输出流。因此,它将覆盖ouputstream中的现有数据。在您的情况下,由于marshallerObj.marshal(student, new FileOutputStream("User.xml"));位于循环内,因此最终文件将始终包含列表中的最后一个对象。即,在第一次迭代中,它将第一个对象写入文件,在第二次迭代中,它将用第二个对象覆盖文件,在第三次迭代中,它将用第三个对象覆盖文件,依此类推。

要编组对象列表,其中一个解决方案是创建一个容器对象,该对象将维护所有用户/学生的列表,然后封送容器对象。

有关类似问题,请参阅link

在您的情况下,容器类应该类似于:

@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);
    }
}

编组用户的代码:

Users users = new Users();

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

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

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