@XmlElements отмечены @XmlJavaTypeAdapters?

у меня такая ситуация

@XmlType(name ="", propOrder={"value"})
@XmlRootElement(name = "compound")
public class Compound extends Value {
  @XmlElements({
  @XmlElement(name="simple", type=Simple.class),
  @XmlElement(name="compound", type=Compound.class)
  })
  protected List<Value> value;
  // ...
}

Таким образом, соединение представляет собой список как простых, так и / или составных. Оба простираются от значения, которое определяется как

public abstract class Value implements Serializable {}

Simple — это класс, помеченный адаптером для маршалинга/демаршалирования в/из простой строки.

@XmlJavaTypeAdapter(SimpleAdapter.class)
public class Simple extends Value {
  private java.lang.String simple;
  // ...
}

Соединение не нуждается в адаптере.

Проблема в том, что если я использую Simple «как есть», он правильно маршалирует/демаршалирует как

<simple>my.text.here</simple>

но если я использую его внутри соединения, он выводит что-то вроде

<compound>
  //...
  <simple>
    <value>my.text.here</value>
  </simple>
  //...
</compound>

И мне просто интересно, почему... Я что-то пропустил? Как я могу удалить это «значение»? Мне кажется, что Адаптер вообще не используется, можно ли использовать адаптеры в типах, отмеченных внутри @XmlElements?

ИЗМЕНИТЬ

После нескольких тестов я обнаружил, что проблема может заключаться в том, как я обрабатываю экземпляр Simple. Поэтому я упрощаю свой первоначальный вопрос:

Учитывая простой класс, например

@XmlRootElement("simple")
public class Simple {
  private java.lang.String innerText;
  // getters/setters
}

как я могу получить упорядоченный вывод, например

<simple>
  my.inner.text.here
</simple>

вместо

<simple>
  <value>my.inner.text.here</value>
</simple>

?


person Andrea Boscolo    schedule 21.05.2011    source источник
comment
Незначительная вещь. Вы написали, что и Compound, и Simple наследуются от Value, но это не отражено в их определениях.   -  person Grzegorz Oledzki    schedule 22.05.2011
comment
Еще одна вещь. Вы уверены, что вывод, если он упорядочен внутри Compound, равен <simple><value>my.text.here</value></simple>, а не <simple><simple>my.text.here</simple></simple>? Я бы понял последнее, но я не понимаю, почему произошло бы первое. Где определено имя элемента value?   -  person Grzegorz Oledzki    schedule 23.05.2011
comment
В общем, похоже, что у вас гораздо большая модель, и вы вручную извлекаете самые важные вещи и публикуете их здесь. Я не уверен, что вы их запускаете. Может быть, было бы здорово, если бы вы извлекли простой пример (как вы пытаетесь), запустили его и поделились с нами всем контекстом и результатом?   -  person Grzegorz Oledzki    schedule 23.05.2011
comment
Вы правы, это всего лишь фрагмент более крупной сгенерированной (и сильно отредактированной) схемы, которую мне не разрешено публиковать. В любом случае я попытаюсь сделать простой тестовый пример, чтобы показать, что я имею в виду. Я отредактировал образец, чтобы исправить наследование, и нет, я не знаю, откуда взялось это «значение».   -  person Andrea Boscolo    schedule 23.05.2011
comment
Причина, по которой я разместил эти комментарии, заключается в том, что я попытался сделать то, что, как я думал, соответствует вашему описанию, но мои результаты были другими. И, как обычно, это детали, которые имеют значение. Я прекрасно понимаю, что о размещении всей модели не может быть и речи, но даже это возможно, это не будет хорошим примером.   -  person Grzegorz Oledzki    schedule 23.05.2011
comment
После нескольких тестов я упростил вопрос.   -  person Andrea Boscolo    schedule 24.05.2011


Ответы (2)


Похоже, вы хотите, чтобы private java.lang.String innerText; было @XmlValue вашего класса Simple. Попробуйте аннотировать строку в Simple с помощью тега @XmlValue:

@XmlRootElement("simple")
public class Simple {
  @XmlValue
  private java.lang.String innerText;
  //getters/setters
}

Или, если вы использовали аннотации в своем методе получения (что я предполагаю на основе вашего вывода XML в вопросе, измените свой тег @XmlElement на тег @XmlValue:

@XmlValue
public java.lang.String getInnerText() {
  return innerText;
}

Когда я это делаю, я получаю результат, который вы ищете в своем отредактированном вопросе.

person bamana    schedule 23.05.2011
comment
Спасибо, теперь проблема в другом... Простой класс расширяет абстрактный базовый класс с именем Value. Когда я пытаюсь упорядочить его, я получаю что-то вроде Свойство или поле не могут быть аннотированы с помощью XmlValue, так как это подкласс другого класса. Как я могу это решить? - person Andrea Boscolo; 24.05.2011
comment
Хорошо, добавьте @XmlTransient в класс Value. Это должно решить проблему. - person bamana; 24.05.2011
comment
@ciosbel вы пробовали аннотацию @XmlTransient для класса Value? Это дало мне результат, который вы искали, с реализацией, которую я предоставил выше. - person bamana; 28.05.2011

ответ, данный bamana, является правильным, однако исключение, которое вы видите, связано к ошибке в эталонной реализации JAXB. Эта ошибка также существовала в EclipseLink JAXB (MOXy), но была исправлена ​​в версии 2.3. 0, ночную загрузку можно получить здесь:

В качестве обходного пути вы можете использовать подход XmlAdapter, который был в вашем исходном вопросе:

Простой адаптер

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class SimpleAdapter extends XmlAdapter<String, Simple> {

    @Override
    public Simple unmarshal(String v) throws Exception {
        Simple simple = new Simple();
        simple.setSimple(v);
        return simple;
    }

    @Override
    public String marshal(Simple v) throws Exception {
        return v.getSimple();
    }

}

Простой

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlJavaTypeAdapter(SimpleAdapter.class)
public class Simple extends Value {
    private java.lang.String simple;

    public java.lang.String getSimple() {
        return simple;
    }

    public void setSimple(java.lang.String simple) {
        this.simple = simple;
    }

}

Составной

import java.util.List;

import javax.xml.bind.annotation.*;

@XmlRootElement(name = "compound")
@XmlAccessorType(XmlAccessType.FIELD)
public class Compound extends Value {
    @XmlElements({ @XmlElement(name = "simple", type = Simple.class),
            @XmlElement(name = "compound", type = Compound.class) })
    protected List<Value> value;

    public List<Value> getValue() {
        return value;
    }

    public void setValue(List<Value> value) {
        this.value = value;
    }

}

Значение

import java.io.Serializable;

public abstract class Value implements Serializable {}

Демо

import java.io.File;

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

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Compound compound = (Compound) unmarshaller.unmarshal(new File("input.xml"));
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(compound, System.out);
    }

}

входной файл.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<compound>
    <simple>
        <simple>FOO</simple>
    </simple>
    <compound/>
</compound>
person bdoughan    schedule 24.05.2011
comment
Это была именно моя первоначальная идея, но я не хочу, чтобы простой файл сортировался, как ваш входной файл, без этой внутренней «простой» оболочки. - person Andrea Boscolo; 24.05.2011
comment
@ciosbel - я считаю, что поведение, которое вы видите, является ошибкой, в настоящее время я пытаюсь исправить это поведение в EclipseLink JAXB (MOXy). Однако, если вы используете MOXy, вы все равно можете использовать @XmlValue без @XmlJavaTypeAdapter. - person bdoughan; 24.05.2011
comment
@ciosbel — ход решения этой проблемы в EclipseLink JAXB (MOXy) можно отслеживать по следующей ошибке: bugs.eclipse. орг/347026 - person bdoughan; 24.05.2011
comment
Так что это ошибка. Спасибо. Если безболезненно, попробую переключиться на реализацию MOXy и протестировать подсказку @XmlValue. - person Andrea Boscolo; 25.05.2011