JAXB смущен корневыми элементами? - PullRequest
5 голосов
/ 16 декабря 2011

Я пытаюсь упорядочить файл, используя Visio XML Schema , который состоит из 3 файлов схемы и создает три пакета, когда исходный код Java создается с XJC:

  • com.microsoft.schemas.visio._2003.core
  • com.microsoft.schemas.visio._2006.extension
  • com.microsoft.schemas.office.visio._2010.extension

Корневым элементом является VisioDocument, и все используемые мной классы находятся в пакете 2003.

Вот мой подход к упорядочиванию моего XML-файла:

VisioDocumentType visioDoc = new VisioDocumentType();
... manipulated here ...
JAXBContext jc = JAXBContext.newInstance("com.microsoft.schemas.visio._2003.core");
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(new JAXBElement<VisioDocumentType>(new QName("uri","local"), VisioDocumentType.class, visioDoc), bw);

При выполнении я получаю эту ошибку:

javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "com.microsoft.schemas.visio._2003.core.PagePropsType" as an element because it is missing an @XmlRootElement annotation]

Я использую PagePropsType, но это не корневой элемент. Почему JAXB так думает?

Ответы [ 2 ]

2 голосов
/ 16 декабря 2011

Проблема заключается в ... manipulated here ... части вашего кода.

Исходя из предположения, что вы делаете следующее (или что-то подобное).

// you create a page prop
PagePropsType pageProps = ...

// then you feed it to a shape sheet
ShapeSheetType shapeSheet = ...
shapeSheet.getTextOrXFormOrLine().add(pageProps);

(ShapeSheetType - суперкласс для StyleSheetType и т. Д.)

Если это так, то ваша проблема заключается в добавлении pageProps в список напрямую.

Если вы посмотрите на документацию по методу getTextOrXFormOrLine(), в ней перечислены типы типов, которые может содержать этот список. Каждый тип обернут в JAXBElement<...>, поэтому перед добавлением его в список необходимо обернуть pageProps.

Вы должны сделать это так:

ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<PagePropsType> pagePropsElement = objectFactory.createShapeSheetTypePageProps(pageProps);

(Обратите внимание, что я использовал XJC 2.2.4 для компиляции схем; для меня каждое имя класса имеет суффикс Type. Возможно, поэтому я в итоге получил VisioDocumentType вместо VisioDocument как вы, но это не должно иметь значения.)

1 голос
/ 16 декабря 2011

Если вы проверите свой сгенерированный код, вы найдете там класс ObjectFactory. Этот класс должен иметь метод, который возвращает VisioDocument, завернутый в JAXBElement, и тот объект, который вы хотите передать маршаллеру.

То же самое относится ко всем объектам, которые вы устанавливаете внутри VisioDocument - не создавайте их с помощью 'new', а используйте ObjectFactory.

...