EclipseLink Moxy unmarshall具有不同元素名称的Collection

时间:2013-12-23 14:42:45

标签: java xml jaxb eclipselink moxy

我有一个包含ArrayList(SuperClass)属性的类。现在我希望解组以下XML文件,该文件包含该集合中的不同元素名称,因为它们是Superclass的子类。有没有办法用Moxy做到这一点?

<?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位于我的smMessage基类的java对象模型子类中,该子类由SmMessageSet类保存,如上所述,是SmMessage类的ArrayList。

我还想不改变当前的XML结构(即在XML文件中围绕SmMessages创建一个包装元素)。

任何帮助将不胜感激:)

1 个答案:

答案 0 :(得分:0)

您可以使用@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>