Java 如何使用JAXB将数据写入XML文件?
我使用eclipse链接,从表中检索数据,并尝试使用JAXB将检索到的数据存储到XML文件中。写入XML文件时,最后一条记录仅保存在该文件中 这里的User是我的POJO类,有两个字段Java 如何使用JAXB将数据写入XML文件?,java,xml,jpa,jaxb,eclipselink,Java,Xml,Jpa,Jaxb,Eclipselink,我使用eclipse链接,从表中检索数据,并尝试使用JAXB将检索到的数据存储到XML文件中。写入XML文件时,最后一条记录仅保存在该文件中 这里的User是我的POJO类,有两个字段 @XmlRootElement public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDE
@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();
}
}
}
公共类ObjectToXml{
私有静态int启动索引=0;
私有静态int maxIndex=10;
公共静态void main(字符串[]args){
EntityManager EntityManager=EntityManagerUtil.getEmf()
.createEntityManager();
Query Query=entityManager.createQuery(“从用户u中选择u”);
System.out.println(“记录总数”
+query.getResultList().size());
试一试{
JAXBContext contextObj=JAXBContext.newInstance(User.class);
Marshaller marshallerObj=contextObj.createMarshaller();
setProperty(Marshaller.JAXB_格式化的_输出,true);
query.setFirstResult(startingIndex);
query.setMaxResults(maxIndex);
List user=query.getResultList();
迭代器迭代器=user.Iterator();
while(iterator.hasNext()){
用户student=(用户)迭代器.next();
MarshallerObj.marshall(学生,新文件输出流(“User.xml”);
}
}捕获(例外e){
e、 printStackTrace();
}
最后{
entityManager.close();
}
}
}
这里我得到了10条记录,但在存储最后一条记录时,它只保存在XML中
我的结果是:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<user id="10">
<name>prabha</name>
</user>
普拉巴
也许您应该保留一个文件输出流
并不断地在其中进行marshall,而不是在每次迭代中创建一个新的。因为MarshallerObj.marshall(学生,新文件输出流(“User.xml”)代码>每次创建新文件o/p流并清除以前的内容。从while循环中创建此o/p流实例。这应该会有所帮助。因为您正在为每个用户对象创建xml文件,所以当程序从DB中接收新用户时,这些对象将不断被替换
因此,创建一个POJO类Users,将用户列表作为属性,
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;
}
现在修改while循环,将所有用户信息设置为Users对象,并将Users对象设置为marshar,而不是封送用户对象
您需要使用@xmlements
注释
Marshaller.marshall()
只需将对象转换为字节流并写入输出流。因此,它将覆盖OutStream中的现有数据。在您的例子中,因为marshallerObj.marshall(学生,新的FileOutputStream(“User.xml”)如果代码>位于循环中,则最终文件将始终包含列表中的最后一个对象。即,在第一次迭代中,它将第一个对象写入文件,在第二次迭代中,它将用第二个对象覆盖文件,在第三次迭代中,它将用第三个对象覆盖文件,依此类推
要封送一个对象列表,解决方案之一是创建一个容器对象,它将维护一个所有用户/学生的列表,然后封送容器对象
有关类似问题,请参阅
在您的情况下,容器类应该如下所示:
@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);
}
}
@XmlRootElement(name=“Users”)
公共类用户
{
private List users=new ArrayList();
@XmlElements(值={@XmlElement(name=“User”,type=User.class)})
@XmlElementWrapper
公共列表getUsers(){
返回用户;
}
public void addUser(用户){
用户。添加(用户);
}
}
以及封送用户的代码:
Users users = new Users();
List<User> usersList = query.getResultList();
for(User user : usersList) {
users.addUser(user);
}
marshallerObj.marshal(users, new FileOutputStream("User.xml"));
Users=新用户();
List usersList=query.getResultList();
for(用户:usersList){
users.addUser(用户);
}
marshallerObj.marshall(用户,新文件输出流(“User.xml”);
谢谢,所以我要做的是FileOutputStream fos=newfileoutputstream(“User.xml”);而(iterator.hasNext()){User student=(User)iterator.next();MarshallerObj.marshal(student,fos);}XML文档中只允许一个顶级元素。处理资源时出错…当我打开XML时,它显示为这样尝试封送整个用户
列表,而不是每个用户。你的意思是在while循环之外,我必须封送naThank你,我把它放在while循环的out端,但结果是一样的。我为循环外的用户创建了新对象,并将其写入System.out而不是文件输出流,然后查看它打印了什么。打印10个对象。发布包含文件o/p流和while loopcom.company的代码块。User@45389b3fcom.com公司。User@758689a com.com公司。User@3d3b5a3acom.com公司。User@3a0b53ecom.com公司。User@2bdafb4ecom.com公司。User@535c97e4com.com公司。User@63f8247dcom.com公司。User@3823bdd1com.com公司。User@32830122com.com公司。User@36bf7916Also您需要使用JAXBContext contextObj=JAXBContext.newInstance(User.class,Users.class)将用户类添加到上下文中代码>谢谢@Sanket Meghani,我在user3156284的帮助下获得了o/p。我现在编辑了您的代码,我只在您的代码的帮助下获得了o/p。非常感谢@user3156284。如果答案对您有帮助,请将其标记为正确。:)
@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"));