JAXB 2.x: как демонтировать XML, не зная целевого класса? - PullRequest
7 голосов
/ 01 апреля 2011

Если есть способ, как это сделать, я бы хотел узнать самый элегантный.Вот вопрос: - Давайте предположим, что у вас есть абстрактный класс Z - У вас есть два класса, унаследованных от Z: с именами A и B.

Вы маршалируете любой экземпляр (A или B) следующим образом:

JAXBContext context = JAXBContext.newInstance(Z.class);
Marshaller m = context.createMarshaller();
m.marshal(jaxbObject, ...an outputstream...);

В полученном XML вы видите, какой это был экземпляр (A или B).

Теперь, как вы можете unmarshall, как

JAXBContext jc = JAXBContext.newInstance(Z.class);
Unmarshaller u = jc.createUnmarshaller();
u.unmarshal(...an inputstream...)

Я получаю исключение UnmarshalException

"Exception Description: A descriptor with default root element {<my namespace>}<the root tag, e.g. A or B> was not found in the project]

javax.xml.bind.UnmarshalException "

Итак, как вы делаете демаршаллинг, чтобы получить экземпляр Z, а затем вы можете протестировать ПОСЛЕ демаршаллингачто это такое? например, z instanceof A затем ... z instanceof B, затем что-то еще ... etc.

Спасибо за любые идеи или решения.

Я использую JRE1.6 сМОКСИ как JAXB Impl.

Ответы [ 4 ]

4 голосов
/ 01 апреля 2011

Есть похожий вопрос здесь .

Возможно ли просто демаршировать, предоставив Person.class, и демон маршаллер узнает сам, должен ли он демаршировать до ReceiverPerson.class или SenderPerson.class?

@XmlRootElement(name="person")
public class ReceiverPerson extends Person {
  // receiver specific code
}

@XmlRootElement(name="person")
public class SenderPerson extends Person {
  // sender specific code (if any)
}

// note: no @XmlRootElement here
public class Person {
  // data model + jaxb annotations here
}
1 голос
/ 02 мая 2011

НЕТ РЕШЕНИЯ ДЛЯ МОЕГО ВОПРОСА!

При любых обстоятельствах вы должны точно сказать демонстрантеру, к какому объекту он должен демаршироваться.

0 голосов
/ 26 августа 2011

Итак, как вы делаете демаршаллинг, чтобы получить экземпляр Z, а затем вы можете проверить> ПОСЛЕ демаршаллинга, что это такое? например z экземпляр A затем ... z экземпляр B затем> что-то еще ... и т. д.

Это должно работать ...

Unmarshaller u = jc.createUnmarshaller();
Object ooo = u.unmarshal( xmlStream );
if ( ooo instanceof A )
{
    A myAclass = (A)ooo;
}
else if ( ooo instanceof B )
{
    B myBclass = (B)ooo;
}

Я сам проверил это, и оно работает.

0 голосов
/ 01 апреля 2011

Каждый XML-документ должен иметь корневой элемент , и если вы хотите использовать один и тот же UnMarshaller для обоих случаев, ваша единственная возможность - иметь общий корневой элемент, например:

<root>
  <A></A>
</root>

и ваш xsd файл будет выглядеть так

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:annotation>
        <xs:documentation>
        example for stackoverflow
    </xs:documentation>
    </xs:annotation>
    <xs:element name="root" type="rootType"/>
    <xs:complexType name="rootType">
            <xs:choice>
                <xs:element name="A" type="AType"/>
                <xs:element name="B" type="BType"/>
            </xs:choice>
    </xs:complexType>

    ... your AType and BType definitions here

</xs:schema>
...