对于JAXB,我希望取消包含以下几个序列化对象的xml文档:
<?xml version="1.0" encoding="UTF-8"?>
<Users>
<User>
<firstName>first name value 1</firstName>
<lastName>last name value 1</lastName>
<account>
<expiration>expire 1</expiration>
<login>login 1</login>
</account>
</User>
<User>
<firstName>first name value 2</firstName>
<lastName>last name value 2</lastName>
<account>
<expiration>expire 2</expiration>
<login>login 2</login>
</account>
</User>
...
</Users>事实上,我不想创建一个名为“User”的新类,它包含一个用户元素列表(带有@XmlWrapper注释)。
下面是我必须转换成xml的java对象:
@Entity
@Table(name="USERS")
@XmlRootElement(name="User")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
@OneToOne(cascade={CascadeType.REMOVE}, mappedBy="user")
private Account account;
@XmlAttribute
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@XmlElement
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@XmlElement
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@XmlInverseReference(mappedBy="user")
@XmlElement
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
}目前,我只需向用户java对象解锁一个xml。就像这样:
@Test
public void test2() {
try {
JAXBContext jc = JAXBContext.newInstance(User.class);
Unmarshaller u = jc.createUnmarshaller();
File f = new File("user.xml");
User element = (User) u.unmarshal(f);
System.out.println(
element.getAccount().getLogin()
);
} catch (JAXBException e) {
e.printStackTrace();
}
}我希望得到一个用户java列表实例,而不仅仅是一个用户实例。例如,像这样:
List<User> elements = (List<User>) u.unmarshal(f);我希望这是可能的,我想知道如何做到;)
非常感谢你的回复,布莱斯。
我试着像你做的那样做,但我错了:
com.sun.org.apache.xerces.internal.dom.ElementNSImpl不能转换为com.thales.momoko.ws.model.User
下面是我代码的一些相关部分:
public class Tools<T> {
public List<T> getItems(Class<T> entityClass, String xmlLocation) {
try {
JAXBContext jc = JAXBContext.newInstance(Wrapper.class, entityClass.getClass());
Unmarshaller unmarshaller = jc.createUnmarshaller();
BufferedReader br = new BufferedReader(
new InputStreamReader(
this.getClass().getClassLoader().getResourceAsStream(xmlLocation)));
System.out.println(br.readLine());
Wrapper<T> wrapper = (Wrapper<T>) unmarshaller.unmarshal(new StreamSource(br), Wrapper.class).getValue();
System.out.println(wrapper);
return wrapper.getItems();
} catch (JAXBException ex) {
Logger.getLogger(Tools.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Tools.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}第一个println运行良好,因为它显示了xml文件的第一行:
<?xml version=....>第二个println显示了解编组的问题:
包装器{items=[用户:空,用户:空]}
包装:
public class Wrapper<T> {
private List<T> items = new ArrayList<>();
@XmlAnyElement(lax=true)
public List<T> getItems() {
return items;
}
@Override
public String toString() {
return "Wrapper{" + "items=" + items + '}';
}
}最后是解封员的呼唤:
@PostConstruct
public void init() {
this.entityClass = User.class;
for (User user : (List<User>) new Tools<User>().getItems(User.class, "user.xml"))
System.out.println(user.getFirstName());
}它在"for“指令行上给出了一个错误。
你对这个错误有什么想法吗?
下次谢了!
编辑
解决办法:
public class Tools<T> {
public static <T> List<T> getItems(Class<T> entityClass, String xmlLocation) {
try {
JAXBContext jc;
synchronized (JAXBContext.class) {
jc = JAXBContext.newInstance(Wrapper.class, entityClass);
}
Unmarshaller unmarshaller = jc.createUnmarshaller();
BufferedReader br = new BufferedReader(
new InputStreamReader(
Import.class.getClassLoader().getResourceAsStream(xmlLocation)));
Wrapper<T> wrapper = (Wrapper<T>) unmarshaller.unmarshal(new StreamSource(br), Wrapper.class).getValue();
return wrapper.getItems();
} catch (JAXBException ex) {
Logger.getLogger(Import.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}呼吁:
@PostConstruct
public void init() {
this.entityClass = User.class;
for (User user : (List<User>) Tools.getItems(User.class, "user.xml"))
em.persist(user);
}发布于 2013-06-13 16:58:22
您可以使用JAXB与StAX一起执行以下操作:
import java.util.*;
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(User.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
StreamSource xml = new StreamSource("src/forum17047306/input.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(xml);
List<User> users = new ArrayList<User>();
Unmarshaller unmarshaller = jc.createUnmarshaller();
while(xsr.getEventType() != XMLStreamReader.END_DOCUMENT) {
if(xsr.isStartElement() && "User".equals(xsr.getLocalName())) {
User user = (User) unmarshaller.unmarshal(xsr);
users.add(user);
}
xsr.next();
}
System.out.println(users.size());
}
}更新
您可能更喜欢使用泛型列表包装对象处理列表的下列方法:
https://stackoverflow.com/questions/17047306
复制相似问题