EclipseLink Moxy unmarshall Коллекция с разными именами элементов
У меня есть класс, который содержит свойство ArrayList (SuperClass). Теперь я хочу удалить следующий XML-файл, который содержит разные имена элементов в этой коллекции, потому что это подклассы суперкласса. Есть ли способ сделать это с Мокси?
<?xml version="1.0" encoding="UTF-8"?>
<SmMessageSet xmlns:nav="urn:ccsds:recommendation:navigation:schema:ndmxml:R1.5"
xmlns="urn:ccsds:recommendation:service_management:schema:sccs:R1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ccsds:recommendation:service_management:schema:sccs:R1.0 file:/C:/CCSDS-910.11-B-1_XML_schemas/CCSDS-910.11-B-1_XML_schemas/SmSchema-v1.0.0.xsd">
<sccsSmVersionRef>sccsSmVersionRef0</sccsSmVersionRef>
<smSource>smSource0</smSource>
<smDestination>smDestination0</smDestination>
<serviceAgreementRef>serviceAgreementRef0</serviceAgreementRef>
<smMessages>
<querySpaceCommunicationServiceProfileFailedReturn>
<messageSequenceNumber>50</messageSequenceNumber>
<messageTimestamp>2006-05-04T18:13:51.0</messageTimestamp>
<invocationMessageSequenceNumber>50</invocationMessageSequenceNumber>
<spaceCommunicationServiceProfileRef>spaceCommunicationServiceProfileRef0
</spaceCommunicationServiceProfileRef>
<qscspError>
<erroredItem>erroredItem0</erroredItem>
<diagnostic>operation timeout</diagnostic>
</qscspError>
<qscspError>
<erroredItem>erroredItem1</erroredItem>
<diagnostic>operation timeout</diagnostic>
</qscspError>
</querySpaceCommunicationServiceProfileFailedReturn>
<createUserAccountInvocation1>
<messageSequenceNumber>50</messageSequenceNumber>
<messageTimestamp>2006-05-04T18:13:51.0</messageTimestamp>
<username>createdUser</username>
<password>createdPassword</password>
<firstname>Test</firstname>
<lastname>User</lastname>
<email>test.user@host.de</email>
<role>SCHEDULING_OFFICER</role>
<superuser>0</superuser>
</createUserAccountInvocation1>
</smMessages>
</SmMessageSet>
QuerySpaceCommunicationServiceProfileFailedReturn и createUserAccountInvocation находятся в моих подклассах объектной модели java базового класса SmMessage, который содержится классом SmMessageSet в, как описано выше, ArrayList классов SmMessage.
Я также хотел бы не изменять текущую структуру XML (т.е. создать элемент-оболочку вокруг SmMessages в файле XML).
Любая помощь будет оценена:)
1 ответ
Вы могли бы сделать следующее используя @XmlElementWrapper
а также @XmlElementRef
:
Модель Java
SmMessageSet
Вы можете использовать @XmlElementWrapper
аннотация для добавления группирующего элемента вокруг коллекции (см.: http://blog.bdoughan.com/2010/09/jaxb-collection-properties.html). Вы также можете использовать @XmlElementRef
аннотация для моделирования имени элемента в качестве индикатора наследования (группы подстановок в XML-схеме см. по адресу: http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html).
package forum20745762;
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="SmMessageSet")
@XmlAccessorType(XmlAccessType.FIELD)
public class SmMessageSet {
@XmlElementWrapper
@XmlElementRef
private List<SmMessage> smMessages;
}
SmMessage
JAXB / MOXy не будет автоматически извлекать все подклассы класса, поэтому вы можете использовать @XmlSeeAlso
аннотация, чтобы они втянули.
package forum20745762;
import javax.xml.bind.annotation.XmlSeeAlso;
@XmlSeeAlso({CreateUserAccountInvocation.class, QuerySpaceCommunicationServiceProfileFailedReturn1.class})
public class SmMessage {
}
CreateUserAccountInvocation
По одному на каждый из подклассов, которые нужно аннотировать @XmlRootElement
, Это имя элемента, которое @XmlElementRef
аннотация будет соответствовать на.
package forum20745762;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class CreateUserAccountInvocation extends SmMessage {
}
QuerySpaceCommunicationServiceProfileFailedReturn1
package forum20745762;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class QuerySpaceCommunicationServiceProfileFailedReturn1 extends SmMessage {
}
Пакет-инфо
Мы будем использовать уровень пакета @XmlSchema
аннотация для сопоставления пространств имен (см.: http://blog.bdoughan.com/2010/08/jaxb-namespaces.html).
@XmlSchema(
namespace="urn:ccsds:recommendation:service_management:schema:sccs:R1.0",
elementFormDefault=XmlNsForm.QUALIFIED
)
package forum20745762;
import javax.xml.bind.annotation.*;
Демонстрационный код
демонстрация
Следующий демонстрационный код прочитает XML из вашего вопроса, а затем выпишет его обратно.
package forum20745762;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(SmMessageSet.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum20745762/input.xml");
SmMessageSet smMessageSet = (SmMessageSet) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(smMessageSet, System.out);
}
}
Выход
Вывод ниже соответствует только подмножеству вашего XML-документа, который я сопоставил:
<?xml version="1.0" encoding="UTF-8"?>
<SmMessageSet xmlns="urn:ccsds:recommendation:service_management:schema:sccs:R1.0">
<smMessages>
<querySpaceCommunicationServiceProfileFailedReturn1/>
<createUserAccountInvocation/>
</smMessages>
</SmMessageSet>