如何知道Java中JAXB中的下一个元素

时间:2014-07-23 23:51:53

标签: java xml jaxb

我有类似这样的架构

<xs:schema xmlns="http://www.ncpdp.org/schema/SCRIPT" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.ncpdp.org/schema/SCRIPT" elementFormDefault="qualified">
<!-- Message -->
<xs:element name="Message" type="MessageType"/>
<xs:complexType name="MessageType">
    <xs:sequence>
        <xs:element name="Header" type="HeaderType"/>
        <xs:element name="Body" type="BodyType"/>
    </xs:sequence>
</xs:complexType>
<xs:complexType name="HeaderType">
    <xs:sequence>
        <xs:element name="To" type="QualifiedMailAddressType">
        </xs:element>
        <xs:element name="From" type="QualifiedMailAddressType">
        </xs:element>
</xs:complexType>
<!-- Body -->
<xs:complexType name="BodyType">
    <xs:choice>
        <xs:annotation>
            <xs:documentation>UIH-010-4</xs:documentation>
        </xs:annotation>
        <xs:element ref="TEST1"/>
        <xs:element ref="TEST2"/>

    </xs:choice>
</xs:complexType>
    <xs:element name="TEST1">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="Gender" minOccurs="0"/>
            <xs:element name="DateOfBirth" type="DateType" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
    <xs:element name="TEST2">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="salary" minOccurs="0"/>
            <xs:element name="DateOfDeath" type="DateType" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
</xs:schema>

我为此XML生成了JAXB对象。

我的请求消息将在body元素中包含TEST1或TEST2。我想知道的是如何知道它是TEST1还是TEST2。

我知道我们可以通过xPATH读取这个内容,但我很奇怪我们可以通过JAXB生成的类来确定

例如,如果我解组消息

MessageType messageType = helper.unmarshal(message);
BodyType bodyType  =    messageType.getBody();

在bodyType中,它将是TEST1或TEST2。我们如何确定?

4 个答案:

答案 0 :(得分:0)

bodyType.getTest1() != null // true if TEST1

bodyType.getTest2() != null // true if TEST2

答案 1 :(得分:0)

if(null!= body Type.getTEST1())// TYPE 1
if(null!= body Type.getTEST2())// TYPE 2

答案 2 :(得分:0)

XJC是否正确生成此类?

 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "BodyType", propOrder = {
        "test1",
        "test2"
 })
 @XmlRootElement
 public class BodyType implements Serializable{

     private final static long serialVersionUID = 12343L;
     @XmlElement(name = "TEST1")
     protected TEST1 test1;
     @XmlElement(name = "TEST2")
     protected TEST2 test2;

XML Schema choice元素只允许声明中包含的一个元素出现在包含元素中,但对于JAXB来说是两个不同的元素。

您无法验证它,您使用JAXB的唯一解决方案就是&#34; if(bodyType.getTest2() != null)&#34;

答案 3 :(得分:0)

使用您当前的架构唯一的方法是使用getTest1() == null等等,其他的遮阳板会覆盖它。但是,如果您可以更改架构,那么如果您有许多不同类型,则无法为此构建更好的设计模式。

看一下这个模式,我创建了一个名为TESTTYPE的抽象类,TEST1TEST2都扩展并将其赋予BodyType

<xs:schema xmlns="http://www.ncpdp.org/schema/SCRIPT" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.ncpdp.org/schema/SCRIPT" elementFormDefault="qualified">
    <!-- Message -->
    <xs:element name="Message" type="MessageType"/>

    <xs:complexType name="MessageType">
        <xs:sequence>
            <xs:element name="Header" type="HeaderType"/>
            <xs:element name="Body" type="BodyType"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="HeaderType">
        <xs:sequence>
        </xs:sequence>
    </xs:complexType>

    <!-- Body -->
    <xs:complexType name="BodyType">
        <xs:sequence>
            <xs:choice>
                <xs:annotation>
                    <xs:documentation>UIH-010-4</xs:documentation>
                </xs:annotation>
                <!-- ref to the abstract test type complex type -->
                <xs:element name="TESTTYPE" type="TESTTYPE" />
            </xs:choice>
        </xs:sequence>
    </xs:complexType>

    <!-- base type, really an abstract class -->
    <xs:complexType name="TESTTYPE" abstract="true">
    </xs:complexType>

    <!-- TEST1 -->
    <xs:element name="TEST1" type="TEST1"/>
    <xs:complexType name="TEST1">
        <xs:complexContent>
            <!--  java version of class TEST1 extends TESTTYPE -->
            <xs:extension base="TESTTYPE">
                <xs:sequence>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <!-- TEST2 -->
    <xs:element name="TEST2" type="TEST2"/>
    <xs:complexType name="TEST2">
        <xs:complexContent>
            <!--  java version of class TEST2 extends TESTTYPE -->
            <xs:extension base="TESTTYPE">
                <xs:sequence>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

</xs:schema>

这会生成以下BodyType

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "BodyType", propOrder = {
    "testtype"
})
public class BodyType {

    @XmlElement(name = "TESTTYPE")
    protected TESTTYPE testtype;

    public TESTTYPE getTESTTYPE() {
        return testtype;
    }
    public void setTESTTYPE(TESTTYPE value) {
        this.testtype = value;
    }

}

这是TEST1

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TEST1")
public class TEST1 extends TESTTYPE

这是TEST2

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TEST2")
public class TEST2 extends TESTTYPE

这使您可以执行bodyType.getTESTTYPE() instanceof TYPE1bodyType.getTESTTYPE().getClass().getSimpleName()

等操作