Java JAXB使用Map而不是List,但获取XML输出时,就好像Map';s的值是一个列表

Java JAXB使用Map而不是List,但获取XML输出时,就好像Map';s的值是一个列表,java,xml,jaxb,Java,Xml,Jaxb,对于元素类型Foos和Foo,我有一个xml模式: <xs:complexType name="Foos"> <xs:sequence> <xs:element name="foo" type="foo" minOccurs="0" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> <xs:complexType name="Foo

对于元素类型
Foos
Foo
,我有一个xml模式:

<xs:complexType name="Foos">
    <xs:sequence>
        <xs:element name="foo" type="foo" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
</xs:complexType>

<xs:complexType name="Foo">
    <xs:attribute name="name" type="xs:string" use="optional" />
</xs:complexType>
如果我创建了一个名为
myFoos
Foos
实例,则用两个
Foo
填充它,并使用

jaxbContext = JAXBContext.newInstance(Foos.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(myFoos, System.out);
然后根据模式获得输出,如下所示:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Foos", propOrder = {"foo"})
public class Foos {

    protected List<Foo> foo;

    public List<Foo> getFoo() {
        if (foo == null) {
            foo = new ArrayList<Foo>();
        }
        return this.foo;
    }
}
<foos>
    <foo name="foo1"/>
    <foo name="foo2"/>
</foos>
然后我将得到以下XML:

<foos>
    <foo>
        <entry>
            <key name="foo1"/>
            <value  name="foo1"/>
        </entry>
    </part>
    <foo>
        <entry>
            <key name="foo2"/>
            <value  name="foo2"/>
        </entry>
    </part>
</parts>

JB Nizet为我指明了正确的方向,这是值得称赞的:

@XmlAccessorType(XmlAccessType.NONE)
@XmlType(name = "Foos", propOrder = { "foo" })
public class Foos {

    private Map<Foo, Foo> fooMap;

    @XmlElements(value = { @XmlElement })
    public Collection<Foo> getFoo() {
        return getFooMap().values();
    }

    public Map<Foo, Foo> getFooMap() {
        if (fooMap == null) {
            fooMap = new HashMap<Foo, Foo>();
        }
        return this.FooMap;
    }
}
@xmlacessortype(xmlacesstype.NONE)
@XmlType(name=“Foos”,proporter={“foo”})
公共类食品{
私人地图;
@XmlElements(值={@XmlElement})
公共集合getFoo(){
返回getFooMap().values();
}
公共地图getFooMap(){
if(fooMap==null){
fooMap=newhashmap();
}
返回此.FooMap;
}
}
  • 我将
    xmlacesstype
    更改为
    NONE
    ,因为我们不再对字段感兴趣(而是对方法
    getFoo
    感兴趣)
  • @xmlements
    标记方法
    getFoo
    ,以便在xml序列化中使用它
  • 无法通过使用
    XmlAccessType.PROPERTY
    使其正常工作;如果你是,请分享
给定XML
,映射的键是什么,值是什么?在任何情况下,为什么不在Foos类(或更高级别的类)中添加一个方法,将列表转换为映射呢?正如我所说的,映射的值应该输出到XML中。因此,对于xml
foo1
foo2
都是值。钥匙是什么对我的问题无关紧要。如果我现在开始解释,可能会有更多的问题,关于我为什么这么做,完全忽略我问题的主题。为什么我不添加一个方法来将列表转换为地图?我想修改和分析集合(即地图),即:添加新元素,询问某个键是否存在,获取其值。xml输出应该准确地表示(映射值的)内容,因为它在我的程序中的某一点上。如果我通过一个方法从地图创建一个新列表,它将只是一个副本,而不显示实际内容。对吗?或者有没有办法制作一个直接链接到地图值的列表?如果是这样,我很乐意为你准备答案!不,那不是我的建议。JAXB使用getter序列化类的状态。因此,如果有一个getter返回一个列表或一组foo,它将序列化该列表或集合。它不关心getter是否返回一个字段,或者它是否从映射创建一个新列表或一个新集合?它不应该是字段,而应该是属性,因为您确实希望JAXB调用getter。
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(name = "Foos", propOrder = { "foo" })
public class Foos {

    private Map<Foo, Foo> fooMap;

    @XmlElements(value = { @XmlElement })
    public Collection<Foo> getFoo() {
        return getFooMap().values();
    }

    public Map<Foo, Foo> getFooMap() {
        if (fooMap == null) {
            fooMap = new HashMap<Foo, Foo>();
        }
        return this.FooMap;
    }
}