#xml #xml-serialization #jaxb
#xml #xml-сериализация #jaxb
Вопрос:
Я должен сгенерировать xml-элемент, который может иметь в качестве значения любой «примитивный тип» (xsd: string, xsd: boolean и т. Д.). Примеры:
<field xsi:type="xsd:string" name="aString">String Value</field>
<field xsi:type="xsd:dateTime" name="aDate">2011-10-21</field>
<field xsi:type="xsd:dateTime" name="aDateTime">2011-10-21T12:00:00</field>
...
Итак, я использую эту реализацию, которая заставляет JAXB определять xsi:type
тип примитива:
public class Field {
@XmlAttribute
private String name;
@XmlElement
Object value;
}
и он работает, как ожидалось, но все java.util.Дата получает тип xs:dateTime
…
Теперь я хочу изменить поведение маршаллера ТОЛЬКО тогда, когда объект ‘value’ является экземпляром java.util.Дата для получения таких полей:
<field xsi:type="xsd:date" name="aDate">2011-10-21</field>
<field xsi:type="xsd:dateTime" name="aDateTime">2011-10-21T12:00:00</field>
Итак, я создаю адаптер, но если я попробую это:
@XmlElement
@XmlJavaTypeAdapter(DateAdapter.class)
Object value;
Адаптер должен обрабатывать java.lang.Тип объекта
public class DateAdapter extends XmlAdapter<String, Object> {...}
Но я не хочу терять маршаллеры JAXB для всех остальных объектов (Integer, Double и т. Д.)…
есть способ установить адаптер для определенного подтипа элемента?
Комментарии:
1. Вы нашли какое-либо решение для этого?
2. На самом деле нет… У меня есть адаптер, который обрабатывает класс объекта и внутренне управляет каждым подтипом. Это не «приятно», но это работает.
Ответ №1:
Я столкнулся с аналогичной ситуацией, хотя я исходил из XSD и генерировал классы оттуда. Тем не менее, решение также должно быть доступно для вас.
В моих случаях я хотел расширить использование простой строки в модели XSD, чтобы она отображалась как UUID в коде Java, затем другая отображалась как класс в других местах и так далее. Сторона XML, это все string (xs:string), так как же разделить все эти строки на отдельные типы на стороне java…
Что я закончил, так это то, что в XSD я создал простые типы для каждого случая, здесь объявление UUID :
И используйте это вместо строки везде, где требуется.
Затем я создал файл привязок, в котором я указал свои XmlAdaptors, как и вы, за исключением того, что теперь у меня есть отдельные цели и, следовательно, я могу использовать несколько адаптеров, предназначенных специально для каждого xml «types».
Теперь у вас есть дополнительная трудность, заключающаяся в том, что на стороне Java представление вашего поля является просто объектом. Я полагаю, вы затем применяете его, как только узнаете атрибут type. Возможно, создание подкласса field для каждого случая, это позволит вам изменить объявление typeADaptor .
Ответ №2:
попробуйте
http://jaxb.java.net/guide/Mapping_interfaces.html#Use__XmlJavaTypeAdapter
XmlJavaTypeAdapter для интерфейсов с несколькими реализациями
Комментарии:
1. -1 Вы прочитали вопрос? Я реализовал a
XmlAdapter<String, Object>
, но при этом я потерял адаптер дляInteger, Double, etc
. Я хочу сохранить эти адаптеры, и, очевидно, если я использую адаптер для объекта, проще всего сгенерироватьxsi:anyType
, но это именно то, чего я не хочу2. Что касается вашего решения «несколько реализаций», это означает, что я должен обрабатывать
Object
и адаптировать и реализовывать оболочку для каждого подкласса объектов, чтобы сгенерировать правильныйxsi:type
. Опять же, здесь я теряю адаптеры, которые хочу сохранить.