6

我有几种情况,其中 JAXB 从 xsd 文件生成的类具有一系列类列表,其中还包含类列表。生成的类在处理这些情况时使用静态内部类,但这会导致一个类多次存在多个实例。

例如,我有一个存在于多个 xsd 文件中的 Parameter 类。在每个实例中,这个参数类都是相同的,并且包含一个键值对。当为这些 xsd 文件中的每一个生成代码时,每个生成的类都包含一个名为 Parameter 的内部类。

为了减少冗余,我从所有生成的类中删除了 Parameter 类,重新实现它,并更新了所有引用。这按预期工作

当我有另一个类(例如LogicalDevice)也在多个类中实现时,就会出现问题。LogicalDevice 包含一个 ParameterList。当LogicalDevice被提取到自己的类中,并更新引用时,只维护Parameter类中的第一个属性,其余为null。

这让我相信静态内部类有一些特别之处。

供参考的是我的xml和代码

<Jetstream xmlns="http://Jetstream.TersoSolutions.com/v1.1/GetPoliciesResponse">
    <Header/>
    <GetPoliciesResponse>
        <PolicyList>
            <Policy Id="53bb663f-7ed0-41f8-9757-90ad4e015995" Name="MyPolicy"
                 DeviceDefinitionId="f3536a6d-4610-4d56-82d9-54fd6602a883" >
                <ParameterList>
                    <Parameter Name="aggregateeventscancount" Value="2"/>
                    <Parameter Name="aggregateeventscantime" Value="10"/>
                    <Parameter Name="antenna1rxsensitivity" Value="50"/>
                    <Parameter Name="antenna1txpower" Value="30"/>
                    <Parameter Name="antenna2rxsensitivity" Value="50"/>
                    <Parameter Name="antenna2txpower" Value="30"/>
                    <Parameter Name="antenna3rxsensitivity" Value="50"/>
                    <Parameter Name="antenna3txpower" Value="30"/>
                    <Parameter Name="antenna4rxsensitivity" Value="50"/>
                    <Parameter Name="antenna4txpower" Value="30"/>
                    <Parameter Name="commandpollinterval" Value="60"/>
                    <Parameter Name="dns" Value="0.0.0.0"/>
                    <Parameter Name="dooropentimelimit" Value="300"/>
                    <Parameter Name="gateway" Value="0.0.0.0"/>
                    <Parameter Name="ip" Value="0.0.0.0"/>
                    <Parameter Name="jetstreamdeviceurl" Value="https://us-device.tersosolutions.com/v1.0/device/"/>
                    <Parameter Name="lockdownhightemp" Value="127"/>
                    <Parameter Name="lockdownonacpowerfailure" Value="0"/>
                    <Parameter Name="lockdownonreaderfailure" Value="0"/>
                    <Parameter Name="lockdownonhightemp" Value="0"/>
                    <Parameter Name="logentryeventhightemp" Value="127"/>
                    <Parameter Name="logentryeventlowtemp" Value="-128"/>
                    <Parameter Name="numberofantennas" Value="4"/>
                    <Parameter Name="logentrylevel" Value="Warning"/>
                    <Parameter Name="objecteventscancount" Value="2"/>
                    <Parameter Name="objecteventscantime" Value="10"/>
                    <Parameter Name="Subnet" Value="0.0.0.0"/>
                </ParameterList>
                <LogicalDeviceList>
                    <LogicalDevice LogicalDeviceId="MyDevice">
                        <ParameterList>
                            <Parameter Name="ip" value="192.168.91.100" />
                            <Parameter Name="subnet" value="255.255.255.0" />
                            <Parameter Name="gateway" value="192.168.91.1" />
                            <Parameter Name="dns" value="192.168.91.2" />
                        </ParameterList>
                    </LogicalDevice>
                </LogicalDeviceList>
            </Policy>
        </PolicyList>
    </GetPoliciesResponse>
</Jetstream>

以下是修改后的生成代码,参考更新。

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference     Implementation, v2.2.7 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2013.09.09 at 10:24:32 AM CDT 
//


package com.TersoSolutions.Jetstream.SDK.XML.Model.GetPoliciesResponse;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;

import com.TersoSolutions.Jetstream.SDK.XML.LogicalDeviceList;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Jetstream", propOrder = {
"header",
"getPoliciesResponse"
})
@XmlRootElement(name = "Jetstream")
public class Jetstream {

@XmlElement(name = "Header", required = true)
protected Jetstream.Header header;
@XmlElement(name = "GetPoliciesResponse", required = true)
protected Jetstream.GetPoliciesResponse getPoliciesResponse;

/**
 * Gets the value of the header property.
 * 
 * @return
 *     possible object is
 *     {@link Jetstream.Header }
 *     
 */
public Jetstream.Header getHeader() {
    return header;
}

/**
 * Gets the value of the getPoliciesResponse property.
 * 
 * @return
 *     possible object is
 *     {@link Jetstream.GetPoliciesResponse }
 *     
 */
public Jetstream.GetPoliciesResponse getGetPoliciesResponse() {
    return getPoliciesResponse;
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "GetPoliciesResponse", propOrder = {
    "policyList",
    "any"
})
public static class GetPoliciesResponse {

    @XmlElement(name = "PolicyList", required = true)
    protected Jetstream.GetPoliciesResponse.PolicyList policyList;
    @XmlAnyElement(lax = true)
    protected List<Object> any;
    @XmlAnyAttribute
    private Map<QName, String> otherAttributes = new HashMap<QName, String>();

    /**
     * Gets the value of the policyList property.
     * 
     * @return
     *     possible object is
     *     {@link Jetstream.GetPoliciesResponse.PolicyList }
     *     
     */
    public Jetstream.GetPoliciesResponse.PolicyList getPolicyList() {
        return policyList;
    }


    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "PolicyList", propOrder = {
        "policy"
    })
    public static class PolicyList {

        @XmlElement(name = "Policy")
        protected List<Jetstream.GetPoliciesResponse.PolicyList.Policy> policy;

        /**
         * Gets the value of the policy property.
         * 
         * <p>
         * This accessor method returns a reference to the live list,
         * not a snapshot. Therefore any modification you make to the
         * returned list will be present inside the JAXB object.
         * This is why there is not a <CODE>set</CODE> method for the policy property.
         * 
         * <p>
         * For example, to add a new item, do as follows:
         * <pre>
         *    getPolicy().add(newItem);
         * </pre>
         * 
         * 
         * <p>
         * Objects of the following type(s) are allowed in the list
         * {@link Jetstream.GetPoliciesResponse.PolicyList.Policy }
         * 
         * 
         */
        public List<Jetstream.GetPoliciesResponse.PolicyList.Policy> getPolicy() {
            if (policy == null) {
                policy = new ArrayList<Jetstream.GetPoliciesResponse.PolicyList.Policy>();
            }
            return this.policy;
        }

        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "Policy", propOrder = {
            "parameterList",
            "logicalDeviceList",
            "any"
        })
        public static class Policy {

            @XmlElement(name = "ParameterList", required = true)
            protected com.TersoSolutions.Jetstream.SDK.XML.ParameterList parameterList;
            @XmlElement(name = "LogicalDeviceList", required = true)
            protected LogicalDeviceList logicalDeviceList;
            @XmlAnyElement(lax = true)
            protected List<Object> any;
            @XmlAttribute(name = "Id", required = true)
            protected String id;
            @XmlAttribute(name = "Name", required = true)
            protected String name;
            @XmlAttribute(name = "DeviceDefinitionId", required = true)
            protected String deviceDefinitionId;
            @XmlAnyAttribute
            private Map<QName, String> otherAttributes = new HashMap<QName, String>();

            /**
             * Gets the value of the parameterList property.
             * 
             * @return
             *     possible object is
             *     {@link Jetstream.GetPoliciesResponse.PolicyList.Policy.ParameterList }
             *     
             */
            public com.TersoSolutions.Jetstream.SDK.XML.ParameterList getParameterList() {
                return parameterList;
            }

            /**
             * Gets the value of the logicalDeviceList property.
             * 
             * @return
             *     possible object is
             *     {@link Jetstream.GetPoliciesResponse.PolicyList.Policy.LogicalDeviceList }
             *     
             */
            public LogicalDeviceList getLogicalDeviceList() {
                return logicalDeviceList;
            }

            /**
             * Gets the value of the id property.
             * 
             * @return
             *     possible object is
             *     {@link String }
             *     
             */
            public String getId() {
                return id;
            }

            /**
             * Gets the value of the name property.
             * 
             * @return
             *     possible object is
             *     {@link String }
             *     
             */
            public String getName() {
                return name;
            }

            /**
             * Gets the value of the deviceDefinitionId property.
             * 
             * @return
             *     possible object is
             *     {@link String }
             *     
             */
            public String getDeviceDefinitionId() {
                return deviceDefinitionId;
            }

        }

    }

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Header")
public static class Header {

    @XmlAnyAttribute
    private Map<QName, String> otherAttributes = new HashMap<QName, String>();

}

}

这是更新的逻辑设备

package com.TersoSolutions.Jetstream.SDK.XML;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;

import com.TersoSolutions.Jetstream.SDK.XML.Model.GetConfigurationResponse.Jetstream;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "LogicalDeviceList")
public class LogicalDeviceList {

@XmlElement(name = "LogicalDevice")
protected List<LogicalDevice> logicalDevice;

/**
 * Gets the value of the logicalDevice property.
 * 
 * <p>
 * This accessor method returns a reference to the live list,
 * not a snapshot. Therefore any modification you make to the
 * returned list will be present inside the JAXB object.
 * This is why there is not a <CODE>set</CODE> method for the logicalDevice property.
 * 
 * <p>
 * For example, to add a new item, do as follows:
 * <pre>
 *    getLogicalDevice().add(newItem);
 * </pre>
 * 
 * 
 * <p>
 * Objects of the following type(s) are allowed in the list
 * {@link Jetstream.GetConfigurationResponse.LogicalDeviceList.LogicalDevice }
 * 
 * 
 */
public List<LogicalDevice> getLogicalDevice() {
    if (logicalDevice == null) {
        logicalDevice = new ArrayList<LogicalDevice>();
    }
    return this.logicalDevice;
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "LogicalDevice")
public static class LogicalDevice {

    @XmlElement(name = "ParameterList")
    protected com.TersoSolutions.Jetstream.SDK.XML.ParameterList parameterList;
    @XmlAttribute(name = "DeviceDefinitionId")
    protected String deviceDefinitionId;
    @XmlAttribute(name = "DeviceSerialNumber")
    protected String deviceSerialNumber;
    @XmlAttribute(name = "Health")
    protected String health;
    @XmlAttribute(name = "LogicalDeviceId", required = true)
    protected String logicalDeviceId;
    @XmlAttribute(name = "Region")
    protected String region;
    @XmlAttribute(name = "PolicyId")
    protected String policyId;
    @XmlAnyAttribute
    private Map<QName, String> otherAttributes = new HashMap<QName, String>();

    /**
     * Gets the value of the deviceDefinitionId property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getDeviceDefinitionId() {
        return deviceDefinitionId;
    }

    /**
     * Gets the value of the deviceSerialNumber property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getDeviceSerialNumber() {
        return deviceSerialNumber;
    }

    /**
     * Gets the value of the health property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getHealth() {
        return health;
    }


    /**
     * Gets the value of the logicalDeviceId property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getLogicalDeviceId() {
        return logicalDeviceId;
    }


    /**
     * Gets the value of the region property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getRegion() {
        return region;
    }


    /**
     * Gets the value of the policyId property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getPolicyId() {
        return policyId;
    }

    /**
     * Gets the value of the parameterList property.
     * 
     * @return
     *     possible object is
     *     {@link Jetstream.GetPoliciesResponse.PolicyList.Policy.LogicalDeviceList.LogicalDevice.ParameterList }
     *     
     */
    public com.TersoSolutions.Jetstream.SDK.XML.ParameterList getParameterList() {
        return parameterList;
    }

}
}

最后是 Parameter 类

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ParameterList")
public class ParameterList {

@XmlElement(name = "Parameter", required = true)
protected List<com.TersoSolutions.Jetstream.SDK.XML.Parameter> parameter;
@XmlAnyAttribute
private Map<QName, String> otherAttributes = new HashMap<QName, String>();

/**
 * Gets the value of the parameter property.
 * 
 * <p>
 * This accessor method returns a reference to the live list,
 * not a snapshot. Therefore any modification you make to the
 * returned list will be present inside the JAXB object.
 * This is why there is not a <CODE>set</CODE> method for the parameter property.
 * 
 * <p>
 * For example, to add a new item, do as follows:
 * <pre>
 *    getParameter().add(newItem);
 * </pre>
 * 
 * 
 * <p>
 * Objects of the following type(s) are allowed in the list
 * {@link Jetstream.LogEntryEvent.LogEntryList.LogEntry.ParameterList.Parameter }
 * 
 * 
 */
public List<com.TersoSolutions.Jetstream.SDK.XML.Parameter> getParameter() {
    if (parameter == null) {
        parameter = new ArrayList<com.TersoSolutions.Jetstream.SDK.XML.Parameter>();
    }
    return this.parameter;
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Parameter")
public static class Parameter {

    @XmlAttribute(name = "Name", required = true)
    protected String name;
    @XmlAttribute(name = "Value", required = true)
    protected String value;
    @XmlAnyAttribute
    private Map<QName, String> otherAttributes = new HashMap<QName, String>();

    /**
     * Gets the value of the name property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getName() {
        return name;
    }

    /**
     * Gets the value of the value property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getValue() {
        return value;
    }
}
}

重申正在发生的事情。Policy 静态类中包含的 Parameter 数据按预期存在,但 LogicalDevice 下的 Parameter 数据仅包含键,所有值数据都设置为 null。

有谁知道为什么我会因这些更改而丢失数据,或者是什么使静态类变得必要。

4

1 回答 1

1

JAXB (JSR-222)实现将为每个命名复杂类型生成一个顶级类,并为每个匿名复杂类型生成一个静态嵌套类。如果您有逻辑上等价但单独定义的复杂类型,您最终会得到逻辑上等价但单独定义的类。

方法

1 - 模式导入/包含和 JAXB 剧集文件

在一个 XML 模式中定义由其他模式导入/包含的类型。然后,您可以利用剧集文件,以便只为该类型生成一个类。

2 - 使用 JAXB 绑定文件将现有类与复杂类型相关联

您可以使用 JAXB 外部绑定文件让 XJC 使用现有类而不是生成新类。

于 2013-11-14T19:48:16.167 回答