Почему JAXB иногда отображается на JAXBElement? - PullRequest
17 голосов
/ 07 сентября 2010

На есть неофициальный путеводитель со ссылкой на статью, которая (на мой взгляд) кажется совершенно не связанной.

Я использую XJC для генерации своих классов JAXB, и хотя большинство из них отображаются друг на друга, как и ожидалось, некоторые элементы отображаются на JAXBElement<Foo>. Это наиболее раздражает для графов с циклами, где иногда родительским узлом элемента Foo будет JAXBElement<Foo>, который сам не имеет родительского свойства, нарушающего цикл.

Я могу придумать различные обходные пути, но было бы намного приятнее, если бы кто-то мог объяснить мне это поведение. Почему JAXB иногда отображает элемент <Foo> в JAXBElement<Foo> вместо Foo?

Ответы [ 2 ]

10 голосов
/ 07 сентября 2010

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при демаршализации сравните следующие примеры:

0 голосов
/ 11 мая 2017

Чтобы избежать сопоставления с 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, и отметьте «Разрешить расширения поставщика», как показано ниже:

enter image description here

С изменениями я могу избавиться от JAXBElement в сгенерированных классах xjc для конвертации xsd в сгенерированные JAXB классы.

...