JAXB использует Map вместо List, но получает вывод XML, как если бы значения Map были List - PullRequest
0 голосов
/ 01 июля 2018

У меня есть XML-схема для типа элемента Foos и Foo:

<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>

Затем сгенерированный класс для Foos (с использованием xjc, как описано здесь: https://examples.javacodegeeks.com/core-java/xml/bind/jaxb-generate-classes-xsd/) выглядит так:

@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 с именем myFoos, заполните его двумя Foo s и распечатайте его на консоли, используя

jaxbContext = JAXBContext.newInstance(Foos.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(myFoos, System.out);

тогда я получаю вывод в соответствии со схемой, например:

<foos>
    <foo name="foo1"/>
    <foo name="foo2"/>
</foos>

Однако, чтобы лучше обрабатывать мои данные, я хочу использовать Map<Foo, Foo> вместо List<Foo>. Но я не хочу, чтобы выходные данные XML менялись: я хочу, чтобы в XML записывались только ЗНАЧЕНИЯ моей карты; КЛЮЧИ не должны появляться вообще.

Как мне это сделать?

Если я поменяю класс Foos вот так

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

    protected Map<Foo, Foo> foo;

    public Map<Foo, Foo> getFoo() {
        if (foo == null) {
            foo = new HashMap<Foo, Foo>();
        }
        return this.foo;
    }
}

тогда я получу следующий XML:

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

1 Ответ

0 голосов
/ 01 июля 2018

Кредит идет к 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;
    }
}
  • Я изменил XmlAccessType на NONE, потому что нас больше не интересуют поля (а вместо этого метод getFoo).
  • Помеченный метод getFoo с @XmlElements, чтобы использовать его в сериализации xml.
  • Не удалось заставить его работать с помощью XmlAccessType.PROPERTY; если да, поделитесь пожалуйста
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...