JAXB类型问题

时间:2009-04-26 02:09:21

标签: java xml code-generation jaxb

我有一个看起来像这样的xsd(片段):

<xs:complexType name="IDType">
  <xs:choice minOccurs="1" maxOccurs="2">
    <xs:element name="FileID"    minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="IDNumber1" minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="Number"    minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="PNumber"   minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="SS"        minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="Player"    minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="Prior"     minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="BIN"       minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="Mutual"    minOccurs="0" maxOccurs="1" type="an..35" />
  </xs:choice>
</xs:complexType>
<xs:simpleType name="an..35">
  <xs:restriction base="an">
    <xs:maxLength value="35" />
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="an">
   <xs:restriction base="xs:string">
     <xs:pattern value="[ !-~]*" />
   </xs:restriction>
</xs:simpleType>

由于某种原因,这是生成的Java代码:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "IDType", propOrder = {
    "fileID"
})
public class PatientIDType {
    @XmlElementRefs({
        @XmlElementRef(name = "FileED", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "IDNumber1", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "Number", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "PNumber", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "SS", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "Plaer", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "Prior", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "BIN", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "Mutual", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class)
    })
    protected List<JAXBElement<String>> fileID;
    /**
     * Gets the value of the fileID 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 fileID property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getFileID().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     * {@link JAXBElement }{@code <}{@link String }{@code >}
     */
    public List<JAXBElement<String>> getFileID() {
        if (fileID == null) {
            fileID = new ArrayList<JAXBElement<String>>();
        }
        return this.fileID;
    }

为什么类是这样生成的,而不是某种字符串数组?我真的不想每次想要创建东西时都要创建JAXBElements吗?

如何让它为每个只表示字符串或类似字符的类型生成类?

提前致谢,

伊恩

3 个答案:

答案 0 :(得分:6)

生成此代码是因为您的复杂类型IDType包含maxOccurrence大于1的选项,此处:

&lt; xs:choice minOccurs =“1”maxOccurs =“2”&gt;

此列表的内容是具有不同名称但具有相同类型的元素。这在标准的面向对象模型中没有等价物。然后,JAXB使用JAXBElement类来解决此问题:JAXBElement包装一个包含数据的简单对象,并为其分配QName

因此,您可以从此列表中读取并通过提供以下内容明确地写入列表:

  • 数据对象(在您的情况下为String,因为String的所有限制都表示为Java String)
  • JAXBElement getValue()方法返回字符串

JAXB规范包含了如何处理重复选择和重复序列的相当详细和相当复杂的解释。请注意,如果您的序列包含不同类型的对象以及不同的名称,您最终会得到 List&lt; Object&gt;

这是一个很长的解释,现在这里有一些选择:

  • 如果您可以修改架构,请在8个项目周围放置一个包装元素,例如“Wrapper”。包装器将包含单个元素的选择;然后使IDType包含一系列Wrapper元素,其中minOccurs = 1且maxOccurs = 2.
  • 创建一些帮助函数来快速创建JAXBElements。 JAXB在您的目标包中放置了一个可以帮助您的Factory类 - 例如,它包含对Schema命名空间的引用等。

答案 1 :(得分:4)

你的ObjectFActory类应该具有这些值的create方法,类似于

@XmlElementDecl(namespace = "http://www.surescripts.com/messaging", name = "SocialSecurity", scope = PatientIDType.class)
public JAXBElement<String> createPatientIDTypeSocialSecurity(String value) {
    return new JAXBElement<String>(_PayerIDTypeSocialSecurity_QNAME, String.class, PatientIDType.class, value);
}

答案 2 :(得分:1)

如果您正在使用Sun JAXB实现,则可以尝试使用xjc:simple模式进行编译。有关示例,请参阅simplified binding上的文档。应该转

public class PatientIDType {
    protected List<JAXBElement<String>> fileID;
}

进入

public class PatientIDType {
    String fileID;
    ...
}

您需要使用绑定自定义文件编译架构。有关如何操作的示例,请参阅Kohsuke's blog