如何在Java中获取XML抽象元素的实际对象

时间:2018-10-15 11:32:16

标签: java xml intellij-idea xsd

我有以下XSD文件:

msg.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
        attributeFormDefault="unqualified"
        elementFormDefault="qualified"
        targetNamespace="http://xxx.yy/zz/cb"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:cb="http://xxx.yy/zz/cb">

    <xs:complexType name="message">
        <xs:sequence>
            <xs:element ref="cb:abstractGroup" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="baseType">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="fullName" use="required">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:maxLength value="40" />
                        </xs:restriction>
                    </xs:simpleType>
                </xs:attribute>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="actualType1">
        <xs:simpleContent>
            <xs:extension base="cb:baseType">
                <xs:attribute name="title" use="required">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:maxLength value="40" />
                        </xs:restriction>
                    </xs:simpleType>
                </xs:attribute>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="actualType2">
        <xs:simpleContent>
            <xs:extension base="cb:baseType">
                <xs:attribute name="subject" use="required">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:maxLength value="255" />
                        </xs:restriction>
                    </xs:simpleType>
                </xs:attribute>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:element type="cb:actualType1" name="actual1" substitutionGroup="cb:abstractGroup" />
    <xs:element type="cb:actualType2" name="actual2" substitutionGroup="cb:abstractGroup" />

    <xs:element name="abstractGroup" abstract="true" />

    <xs:element name="msg" type="cb:message" />
</xs:schema>

当我使用JAXB在IntellJ IDEA中从此XSD生成Java类时,会得到以下类:

  • ActualType1
  • ActualType2
  • BaseType
  • 消息
  • ObjectFactory

消息类如下:

Message.java

package messages;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for message complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="message">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element ref="{http://xxx.yy/zz/cb}abstractGroup"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "message", namespace = "http://xxx.yy/zz/cb", propOrder = {
    "abstractGroup"
})
public class Message {

    @XmlElementRef(name = "abstractGroup", namespace = "http://xxx.yy/zz/cb", type = JAXBElement.class)
    protected JAXBElement<?> abstractGroup;

    /**
     * Gets the value of the abstractGroup property.
     * 
     * @return
     *     possible object is
     *     {@link JAXBElement }{@code <}{@link Object }{@code >}
     *     {@link JAXBElement }{@code <}{@link ActualType1 }{@code >}
     *     {@link JAXBElement }{@code <}{@link ActualType2 }{@code >}
     *     
     */
    public JAXBElement<?> getAbstractGroup() {
        return abstractGroup;
    }

    /**
     * Sets the value of the abstractGroup property.
     * 
     * @param value
     *     allowed object is
     *     {@link JAXBElement }{@code <}{@link Object }{@code >}
     *     {@link JAXBElement }{@code <}{@link ActualType1 }{@code >}
     *     {@link JAXBElement }{@code <}{@link ActualType2 }{@code >}
     *     
     */
    public void setAbstractGroup(JAXBElement<?> value) {
        this.abstractGroup = value;
    }

}

我有一个示例msg.xml文件:

msg.xml

<cb:msg xmlns:cb="http://xxx.yy/zz/cb">
      <cb:actual1 fullName="bla bla" title="kuku">anyType</cb:actual1>
</cb:msg>

解组后,我想获取代表actual1标签的真实对象。我可以做的是:message.getAbstractGroup(),但是返回JAXBElement<?>的实例,该实例可以是JAXBElement<Object>JAXBElement<ActualType1>JAXBElement<ActualType2>

现在我的问题是:

如何获取类型为ActualType1或至少为BaseType的真实对象,或者如何将JAXBElement<?>转换为ActualType1,ActualType2或BaseType?

1 个答案:

答案 0 :(得分:0)

答案类似于:

BaseType type = (BaseType) message.getAbstractGroup().getValue();

if (type instanceof ActualType1) {
     System.out.println(((ActualType1) type).getTitle());
} else if (type instanceof ActualType2) {
     System.out.println(((ActualType2) type).getSubject());
}