Как я могу использовать JAXB для маршала унаследованных классов в XML? - PullRequest
1 голос
/ 07 марта 2012

Мне был предоставлен xsd, который я скомпилировал для классов Java с использованием JAXB.

Сгенерированные классы создают абстрактный класс с именем "Event" и несколько классов, расширяющих его.
например, "DerivedEvent"Я использую следующее, чтобы упаковать его в XML.

ObjectFactory objectFactory = new ObjectFactory();
DerivedEvent derivedEvent = objectFactory.createDerivedEvent();

JAXBContext context = JAXBContextImpl.newInstance("com.my.root.namespace");
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);

Class partialClass = Event.class;
QName partNamespace = new QName(Event.class.getSimpleName());
Object element = new JAXBElement(partNamespace, partialClass, derivedEvent);
// Create a stringWriter to hold the XML
StringWriter stringWriter = new StringWriter();
marshaller.marshal(element, stringWriter);
String xml = stringWriter.toString(); 

Затем выводится неверный корневой элемент.т. е.

<Event xsi:type="DerivedEvent" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <DerivedStartPeriod xsi:nil="true"/>
    <DerivedEndPeriod xsi:nil="true"/>
</Event>

вместо

<DerivedEvent>
    <DerivedStartPeriod xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
    <DerivedEndPeriod xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</DerivedEvent>

Если я установил для ParticalClass и PartNamespace значение DerivedEvent, оно выведет правильную информацию.Тем не менее, я не могу этого сделать, так как это сортировка происходит в потоке, где событие может быть одним из 50 различных производных событий.

Я не могу действительно изменить xsd, чтобы иметь группы подстановки, как упомянуто здесь http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html, поскольку это изменение может быть потеряно, когда мне будет предоставлена ​​новая версия xsd.

Мне нужно использовать частичный класс и пространство имен, поскольку События не являются корневыми элементами.
Могу ли я как-нибудь добавить события в XmlRootElements с привязками?
Или есть другой способ решения этой проблемы?

Ответы [ 2 ]

1 голос
/ 07 марта 2012

В конце концов я нашел эту страницу, которая помогла мне добавить элемент XmlRootElement:
https://codereview.stackexchange.com/questions/1877/jaxb-xjc-code-generation-adding-xmlrootelement-and-joda-datetime

Над чем я работал (dependencies / build.xml и т. Д.), Используя пример Annotate здесь:
http://confluence.highsource.org/display/J2B/Home

1 голос
/ 07 марта 2012

Создание JAXBElement с помощью сгенерированного ObjectFactory или использование правильного QName.Это плохо:

QName partNamespace = new QName(Event.class.getSimpleName());

Это должно быть так

QName partNamespace = new QName("your namespace", "DerivedEvent");

Вы должны найти qname, как это в ObjectFactory, вероятно, как константа ... ObjectFactory, вероятно, содержит метод createDerivedEvent с одним аргументом типа DerivedEvent.Он возвращает JAXBElement, который может быть преобразован в xml.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...