JAXB XML到Java映射

时间:2018-02-21 14:56:07

标签: java jaxb

我正在尝试将以下XML结构映射到一个巨大的文档中。

以下是文件的一部分:

<operationQueue>
    <pick>...</pick>
    <place>...</place>
    <goTo>...</goTo>
    <toDo>...</toDo>
    ...
    <pick>...</pick>
    <place>...</place>
    <goTo>...</goTo>
    <toDo>...</toDo>    
</operationQueue>

该文档有一个XSD声明可以有无限数组的pick,place,goTo和Todo操作。

我想要的不是为每个元素声明一个不同的数组,比如List,List等。

下面,我到目前为止所尝试的内容:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "operationQueue", propOrder = {
        "pick", "place", "goTo", "toDo"
})

public class OperationQueue {
    @XmlPath("operationQueue/pick")
    @XmlElement(name = "pick")
    public List<Pick> pick;

    @XmlPath("operationQueue/place")
    @XmlElement(name = "place")
    public List<Place> place;

    @XmlPath("operationQueue/goTo")
    @XmlElement(name = "goTo")
    public List<GoTo> goTo;

    @XmlPath("operationQueue/toDo")
    @XmlElement(name = "toDo")
    public List<oDo> toDo;
...
}

这会导致编组和解组问题,并使JSON转换操作变得复杂。 我试图创建一个单独的元素QueueItem,并且每个操作项都增强了它,但是我面临着从JSON问题到Java对象的反序列化。

理想情况下,根据Blaise Doughan的解决方案,它将是一个List<QueueItem>,其中每个操作项都将包含QueueItem元素:Java XML and JSON Binding

@XmlAccessorType(XmlAccessType.FIELD)
public class QueueItem {
    @XmlAttribute
    private String type;

    @XmlValue
    private Object value;

但我遇到了这个解决方案的例外情况:

Exception in thread "main" java.lang.NullPointerException
at com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor.get(TransducedAccessor.java:152)
at com.sun.xml.internal.bind.v2.runtime.property.ValueProperty.<init>(ValueProperty.java:66)
at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:95)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:488)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:507)
at com.sun.xml.internal.bind.v2.runtime.property.SingleElementNodeProperty.<init>(SingleElementNodeProperty.java:90)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:488)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:507)
at com.sun.xml.internal.bind.v2.runtime.property.ArrayElementProperty.<init>(ArrayElementProperty.java:97)
at com.sun.xml.internal.bind.v2.runtime.property.ArrayElementNodeProperty.<init>(ArrayElementNodeProperty.java:47)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:488)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:507)
at com.sun.xml.internal.bind.v2.runtime.property.SingleElementNodeProperty.<init>(SingleElementNodeProperty.java:90)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:113)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:488)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:305)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:147)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:462)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
at com.tideworks.tug.ecs.Main1.main(Main1.java:57)

您对如何实施单一

有任何想法

1 个答案:

答案 0 :(得分:3)

我同意daniu一般你应该使用xsd。

说完这个并且缺少你的案例的背景,一个可以与你所呈现的结合的结构可以是这样的:

您的OperationQueue类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class OperationQueue {

    @XmlElements({
            @XmlElement(name = "pick", type = Pick.class),
            @XmlElement(name = "place", type = Place.class),
            @XmlElement(name = "goTo", type = GoTo.class),
            @XmlElement(name = "toDo", type = ToDo.class),
    })
    public List<QueueItem> item;

}

然后,Pick,Place,GoTo和ToDo类看起来类似于以下内容:

@XmlAccessorType(XmlAccessType.FIELD)
public class Pick implements QueueItem{
    @XmlValue
    private String value;
}

他们都实现了相同的界面,但没有做太多的事情:

public interface QueueItem { }

这将允许您对显示的xml进行编组/解组。

我不确定它是否对你的情况有好处,如果你可以改变你的xsd看起来像这样。但是你对xsd生成List<Object> pickOrPlaceOrGotoOrTodo的评论让我觉得他们在创建xsd时有类似的想法。