Как использовать JAXB @XmlValue в подклассе?

Мне нужен XML:

<simple>Foo</simple>

Я могу сделать это успешно с помощью класса JAXB, который выглядит следующим образом:

@XmlRootElement(name="simple")
class Simple {
    @XmlValue
    public String contents;
}

Но теперь мне нужно сделать класс Simple подклассом другого класса следующим образом:

@XmlRootElement(name="simple")
class Simple extends OtherClass {
    @XmlValue
    public String contents;
}

Это не удается с помощью @XmlValue is not allowed on a class that derives another class. Я не могу с легкостью перенастроить суперкласс (из-за того, как мы используем @XmlElementRef в классе-оболочке). Есть ли обходной путь, который позволит мне аннотировать мой подкласс для создания этого простого XML?

Ответ 1

Примечание. Я EclipseLink JAXB (MOXy) и член группы JAXB 2 (JSR-222).

Этот вариант использования поддерживается MOXy, а IMHO также должен поддерживаться RI JAXB:

Простой

Этот класс имеет поле, отображаемое с помощью @XmlValue и расширяющее OtherClass:

package forum809827;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;

@XmlRootElement(name="simple")
class Simple extends OtherClass {

    @XmlValue
    // @XmlValueExtension
    // As of moxy 2.6, XmlValueExtension needs to be added for this to work
    public String contents;

}

OtherClass

Это суперкласс. В MOXy подкласс может отображать поле/свойство с помощью @XmlValue, если суперкласс не имеет сопоставлений с элементом XML:

package forum809827;

import javax.xml.bind.annotation.XmlAttribute;

public class OtherClass {

    @XmlAttribute
    public String other;

}

Demo

package forum809827;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Simple.class);

        Simple simple = new Simple();
        simple.contents = "FOO";
        simple.other = "BAR";

        Marshaller marshaller = jc.createMarshaller();
        marshaller.marshal(simple, System.out);
    }

}

Выход

<?xml version="1.0" encoding="UTF-8"?>
<simple xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" other="BAR">FOO</simple>

Дополнительные сведения о указании MOXy как поставщика JAXB

Ответ 2

Принятый ответ не сработал у меня.

Все прекрасно, как описано, но мне также необходимо добавить @XmlTransient в суперкласс

Ответ 3

Я смог выполнить эту работу, изменив @XmlValue на @XmlMixed и изменив переменную на список. Полученный класс должен выглядеть следующим образом.

@XmlRootElement(name="simple")
class Simple extends OtherClass {
    @XmlMixed
    public List<String> contents;
}

Ответ 4

Эта проблема возникла со мной, и я немного позаботился. Благодаря Блейзу Дохану Я просматриваю его блог и нахожу ответ

  • вам нужно добавить Файл jaxb.properties с javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory в том же пакете, чтобы использовать MOXy

  • добавить moxy к вашей зависимости maven или добавить moxy jar

    <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>org.eclipse.persistence.moxy</artifactId> <version>2.5.0</version> </dependency>

  • тогда весь набор У меня есть образец, на котором вы можете пойти, хотя мой проект и взглянуть на https://github.com/cicidi/HelloCCD/tree/master/Jaxb