Java JaxB - объект для XML-строки для объекта - программирование
Подтвердить что ты не робот

Java JaxB - объект для XML-строки для объекта

У меня проблема с JaxB в Netbeans 7.1.2.

У меня есть автогенерированные мои классы из схемы с использованием JaxB (New JaxB Binding). Я создаю объект, который будет сериализован в строку XML, используя Marshaller, а затем обратно к экземпляру нового объекта из XML String. Однако я получаю следующее исключение:

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.somewhere.com/some/path", local:"MyQueryComplexTypeQuery"). Expected elements are (none)

Строка marshalling/serializing to XML отлично работает. Это когда он не маршируется/десериализован, что вызывает проблему.

Я использую следующий код для создания объекта и его привязки к XML-строке:

// build the object
ObjectFactory of = new ObjectFactory();

MyQueryComplexType oaaqc = of.createMyQueryComplexType();
oaaqc.setField1("edit");
oaaqc.setField2("net");
oaaqc.setField3("24");

JAXBElement<MyQueryComplexType> createMyQueryComplexType = of.createMyQueryComplexTypeQuery(oaaqc);

// serialise to xml
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(MyQueryComplexType.class);            
Marshaller m = context.createMarshaller();
m.marshal(createMyQueryComplexType, writer);

// output string to console
String theXML = writer.toString();
System.out.println(theXML);

В результате создается следующий XML (отформатированный) в консоли:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyQueryComplexTypeQuery xmlns="http://www.somewhere.com/some/path">
    <Field1>edit</Field1>
    <Field2>net</Field2>
    <Field3>24</Field3>
</MyQueryComplexTypeQuery>

Теперь я пришел к десериализации/развязыванию строки к новому экземпляру MyQueryComplexType со следующим кодом:

Unmarshaller u = context.createUnmarshaller();
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));

В автоматическом сгенерированном package-info.java он имеет следующее содержимое:

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.somewhere.com/some/path", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package MyProject.SomeNamespace.MyQuery;

Я думал, что простой объект объекта → string → будет работать. Это первый раз, когда я использовал JaxB (так что будьте осторожны). Я видел другие сообщения, в которых упоминаются пространства имен, и все выглядит нормально для меня. Я автоматически сгенерировал классы из схемы, построил объект, упорядочил строку xml. Я думал, что просто обратный процесс для немаршала будет похож.

Фактическое исключение выбрано в строке:

MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));

Я думал, что я делаю unmarshalling из строки в объект, было бы просто. Я не знаю, что я делаю что-то неправильно или что-то не хватает. Надеюсь, вы, ребята, можете пролить свет или открыть глаза.

Я сократил код, чтобы упростить то, что в моем приложении вызывает ошибку. Пространства имен были изменены, чтобы защитить личность вещей в Интернете.

Любые мысли?

Спасибо

Andez

4b9b3361

Ответ 1

Создание JAXBContext

Для моделей JAXB, созданных из XML-схемы, вы можете создать JAXBContext в имени пакета, а не в определенном классе:

JAXBContext context = JAXBContext.newInstance("your.package.name");

Не:

JAXBContext context = JAXBContext.newInstance(MyQueryComplexType.class);  

Это гарантирует, что класс ObjectFactory, содержащий аннотации @XmlElementDecl, обрабатывается правильно, чего нет в вашем случае использования.

Работа с немаршалом

Обратите внимание, что во время операции маршала вам нужно было обернуть ваш экземпляр MyQueryComplexType в JAXBElement? Это связано с тем, что MyQueryComplexType не был аннотирован с помощью @XmlRootElement, а информация о корневом элементе должна была поступать из JAXBElement. Это означает, что когда вы выполняете операцию unmarshal, вы также получите обратно JAXBElement.

JAXBElement<MyQueryComplexTypeQuery> o = (JAXBElement<MyQueryComplexType>) u.unmarshal(new StringReader(theXML));

Не:

MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));

Дополнительная информация