将对象的xml列表解组到java列表,而不使用类列表

将对象的xml列表解组到java列表,而不使用类列表,java,xml,jaxb,annotations,unmarshalling,Java,Xml,Jaxb,Annotations,Unmarshalling,使用JAXB,我想解组一个xml文档,该文档包含以下几个序列化对象: <?xml version="1.0" encoding="UTF-8"?> <Users> <User> <firstName>first name value 1</firstName> <lastName>last name value 1</lastName> <account> &l

使用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>
@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();
        }
    }
目前,我只需要将一个xml解组到一个用户java对象。像这样:

<?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>
@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);
List元素=(List)u.unmarshal(f);
我希望这是可能的,我想知道如何做到;)


非常感谢您的回复布莱斯

我试着像你那样做,但我有个错误:

java.lang.ClassCastException: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;
}
}
公共类工具{
公共列表getItems(类entityClass,字符串xmlLocation){
试一试{
JAXBContext jc=JAXBContext.newInstance(Wrapper.class,entityClass.getClass());
Unmarshaller Unmarshaller=jc.createUnmarshaller();
BufferedReader br=新的BufferedReader(
新的InputStreamReader(
this.getClass().getClassLoader().getResourceAsStream(xmlLocation));
System.out.println(br.readLine());
Wrapper=(Wrapper)unmarshaller.unmarshal(newstreamsource(br),Wrapper.class).getValue();
System.out.println(包装器);
返回wrapper.getItems();
}捕获(JAXBEException-ex){
Logger.getLogger(Tools.class.getName()).log(Level.SEVERE,null,ex);
}捕获(IOEX异常){
Logger.getLogger(Tools.class.getName()).log(Level.SEVERE,null,ex);
}
返回null;
}
}
第一个println工作正常,因为它显示xml文件的第一行:

<?xml version=....>

第二个println显示了解组问题:

包装{items=[[user:null]、[user:null]、[user:null]、[user:null]、[user:null]、[user:null]、[user:null]、[user:null]、[user:null]、[user:null]、[user:null]、[user:null]、[user:null]}

包装器:

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 + '}';
}
}
公共类包装器{
私有列表项=新的ArrayList();
@xmlanyement(lax=true)
公共列表getItems(){
退货项目;
}
@凌驾
公共字符串toString(){
返回“包装{“+”项=“+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());
}
@PostConstruct
公共void init(){
this.entityClass=User.class;
对于(用户:(列出)新工具().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;
}
}
公共类工具{
公共静态列表getItems(类entityClass,字符串xmlLocation){
试一试{
jaxbcontextjc;
已同步(JAXBContext.class){
jc=JAXBContext.newInstance(Wrapper.class,entityClass);
}
Unmarshaller Unmarshaller=jc.createUnmarshaller();
BufferedReader br=新的BufferedReader(
新的InputStreamReader(
Import.class.getClassLoader().getResourceAsStream(xmlLocation));
Wrapper=(Wrapper)unmarshaller.unmarshal(newstreamsource(br),Wrapper.class).getValue();
返回wrapper.getItems();
}捕获(JAXBEException-ex){
Logger.getLogger(Import.class.getName()).log(Level.SEVERE,null,ex);
}
返回null;
}
}
电话:

@PostConstruct
public void init() {
   this.entityClass = User.class;
    for (User user : (List<User>) Tools.getItems(User.class, "user.xml"))
        em.persist(user);
}
@PostConstruct
公共void init(){
this.entityClass=User.class;
for(User:(List)Tools.getItems(User.class,“User.xml”))
em.persist(用户);
}

您可以使用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());
    }

}
import java.util.*;
导入javax.xml.bind.*;
导入javax.xml.stream.*;
导入javax.xml.transform.stream.StreamSource;
公开课演示{
公共静态void main(字符串[]args)引发异常{
JAXBContext jc=JAXBContext.newInstance(User.class);
XMLInputFactory xif=XMLInputFactory.newFactory();
StreamSource xml=新的StreamSource(“src/forum17047306/input.xml”);
XMLStreamReader xsr=xif.createXMLStreamReader(xml);
列表用户=新建ArrayList();
Unmarshaller Unmarshaller=jc.createUnmarshaller();
while(xsr.getEventType()!=XMLStreamReader.END_文档){
if(xsr.isStartElement()&&“User”.equals(xsr.getLocalName())){
User=(User)unmarshaller.unmarshal(xsr);
用户。添加(用户);
}
xsr.next();
}
System.out.println(users.size());
}
}

更新

使用通用列表包装器对象处理列表时,您可能更喜欢以下方法:


感谢您的决定!这是一个很好的办法。我现在不需要任何包装纸。