Unmarshalling на основе конкретного экземпляра - PullRequest
2 голосов
/ 21 декабря 2011

Я новичок в JaxB World и столкнулся с одной проблемой w.r.t. демонтаж сохраненного содержимого XML в объект класса java. Описание проблемы заключается в следующем. Дайте мне знать, если это разрешимо У меня есть мой файл xsd, который содержит следующее содержимое (это только пример) Студенческая информация

    <xs:complexType name="specialization" abstract="true">
    </xs:complexType>


    <xs:complexType name="Engineering">
        <xs:complexContent>
            <xs:extension base="specialization">
                <xs:sequence>
                    <xs:element name="percentage" type="xs:int" minOccurs="0"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="Medical">
        <xs:complexContent>
            <xs:extension base="specialization">
                <xs:sequence>
                    <xs:element name="grade" type="xs:string" minOccurs="0"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
</xs:complexType>

Теперь все соответствующие классы Java генерируются путем компиляции xsd. Теперь давайте предположим, что в моем приложении я установлю атрибут специализации информации ученика, создав экземпляр класса Engineering . Так что после всей операции, когда я сохраняю сохраненный XML-файл будет иметь следующую запись:

<Student>
    <Name>Name1</Name>
    <Specialization>
        <percentage>78<percentage>
    </Specialization>
</Student>

Теперь, когда вышеприведенный контент идет на демаршаллинг, демаршаллинг терпит неудачу, говоря неожиданный элемент. Я предполагаю, что это b'cos Элемент специализации имеет специализацию типа, которую он называет демаршаллингом для себя, а не для производного объекта, который хранится.

Надеюсь, мое объяснение понятно. Есть ли способ, которым мы можем unmarshall на основе производного класса instanse типа. Файл xsd и bindings.xjb полностью находится под моим контролем, поэтому я могу добавлять или изменять любые записи / информацию, которые передают в правила демаршаллинга, чтобы демонтировать в производном классе.


Спасибо за ваше предложение, но оно все еще не работает для меня.

Вот что я попробовал

Вариант № 1 - xsi: тип
Мой xsd выглядит так же, как описано в примере, но Xsi: type все равно не входит в полученный xml. Нужно ли добавлять какие-либо другие настройки при компиляции? Какую версию JaxB я должен использовать для этого?

Вариант № 2 - Группы замещения
Когда я добавил часть записи замещения в свой xsd, компиляция XSD не произнесла повторяющихся имен «Engineering» и «Medical». Я предполагаю, что имя элемента и тип Имя совпадают с компиляцией (все инженерные, медицинские, специализация одинаковая и в определении типа, и в имени элемента)

Я не могу изменить сгенерированные классы, так как мы используем модельно-управляемую архитектуру. Единственное, что у вас под рукой, это xsd. Любые изменения в xsd разрешены. В идеале первый вариант должен был сработать. Но не могу понять, почему это не работает. Дайте мне знать, если у вас есть предложение сузить проблему.

1 Ответ

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

Существуют различные способы представления наследования Java в XML при использовании JAXB:

Вариант № 1 - xsi: тип

В этом представлении атрибут используется для указания подтипа, используемого для заполнения этого элемента.

<Student>
    <Name>Name1</Name>
    <Specialization xsi:type="Engineering">
        <percentage>78<percentage>
    </Specialization>
</Student>

Подробный пример см .:

Вариант № 2 - Группы замещения

Здесь имя элемента используется для обозначения подтипа. Это соответствует концепции схемы групп замещения и использует аннотацию @XmlElementRef JAXB:

<Student>
    <Name>Name1</Name>
    <Engineering>
        <percentage>78<percentage>
    </Engineering>
</Student>

Для подробного примера см .:

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