Почему JAXB иногда сопоставляется с JAXBElement?
есть заполнитель ответ на неофициальное руководство со ссылкой на статью, которая (для меня) кажется совершенно не связанной.
Я использую XJC для создания моих классов JAXB, и хотя большинство из них сопоставляются друг с другом, как ожидалось, некоторые элементы сопоставляются с JAXBElement<Foo>
. Это наиболее раздражает для графиков с циклами, где иногда родительский узел элемента Foo будет JAXBElement<Foo>
, который сам по себе не имеет родительского свойства, нарушая цикл.
I можно придумать различные обходные пути, но было бы намного лучше, если бы кто-то мог объяснить мне это поведение. Почему JAXB иногда отображает <Foo>
элемент JAXBElement<Foo>
вместо Foo?
2 ответов
JAXBElement используется для сохранения имени элемента / пространства имен в случаях, когда в объектной модели недостаточно информации. Наиболее распространенное явление - группы замещения:
С Заменой Группы:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org"
xmlns="http://www.example.org"
elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="anElement"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="anElement" type="xs:string"/>
<xs:element name="aSubstituteElement" type="xs:string" substitutionGroup="anElement"/>
</xs:schema>
будет генерировать:
package org.example;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"anElement"
})
@XmlRootElement(name = "root")
public class Root {
@XmlElementRef(name = "anElement", namespace = "http://www.example.org", type = JAXBElement.class)
protected JAXBElement<String> anElement;
public JAXBElement<String> getAnElement() {
return anElement;
}
public void setAnElement(JAXBElement<String> value) {
this.anElement = ((JAXBElement<String> ) value);
}
}
Без Замены Группы:
если удалить группу подстановки:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org"
xmlns="http://www.example.org"
elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="anElement"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="anElement" type="xs:string"/>
</xs:schema>
следующий класс будет сгенерировано:
package org.example;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"anElement"
})
@XmlRootElement(name = "root")
public class Root {
@XmlElement(required = true)
protected String anElement;
public String getAnElement() {
return anElement;
}
public void setAnElement(String value) {
this.anElement = value;
}
}
вы также можете получить JAXBElement, когда вы unmarshal, сравните следующие примеры:
чтобы избежать сопоставления с JAXBElement? Я сделал это работает для меня :
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc"
jaxb:version="2.0">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings generateValueClass="false">
<xjc:simple />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
</xs:schema>
Сохраните этот файл в xml-файле и предоставьте как файлы привязки.
ссылка ссылке
генерировать классы JAXB с помощью eclipse не забудьте дать файлы привязки, созданные с помощью вышеуказанного xml, и проверить "разрешить расширения поставщиков", как показано ниже:
С изменениями, я могу избавиться от JAXBElement в классах сгенерированный XJC для преобразования xsd в JAXB сгенерированные классы.