如何使用 JAXB 从 XML 模式生成 Java 枚举?

Posted

技术标签:

【中文标题】如何使用 JAXB 从 XML 模式生成 Java 枚举?【英文标题】:Howto generate Java Enum from XML Schema with JAXB? 【发布时间】:2011-08-27 06:10:25 【问题描述】:

我正在使用 maven 插件 maven-jaxb2-plugin 从 XSD Schema 文件生成 POJO。 这工作正常。唯一让我感到困扰的是,xml 模式枚举没有映射到 Java 枚举类型中。

我的 maven 插件正在从我称为 schemachooser.xsd 的文件中生成 java pojos

schemachooser.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sch="http://www.ascc.net/xml/schematron" 
targetNamespace="http://schema.something" elementFormDefault="qualified"
version="1.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc" jaxb:version="1.0">

<xs:annotation>
    <xs:appinfo>
        <jaxb:globalBindings generateIsSetMethod="true" fixedAttributeAsConstantProperty="true">
            <xjc:serializable />
        </jaxb:globalBindings>
        <jaxb:schemaBindings>
           <jaxb:bindings node="//xsd:element[@name='ElementName']/xsd:simpleType">
               <jaxb:typesafeEnumClass name="MyEnumType" />
           </jaxb:bindings>
        </jaxb:schemaBindings>
    </xs:appinfo>
</xs:annotation>

<xs:include schemaLocation="myNormalSchema.xsd" />

</schema>

它会生成文件,但不会生成“新”枚举类“MyEnumType”。我是不是用错了绑定?

【问题讨论】:

【参考方案1】:

如果您想将 JAXB 注释与 XML 模式分开,那么您需要使用 JAXB 绑定文件:

bindings.xml

<jaxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    jaxb:extensionBindingPrefixes="xjc"
    version="2.1">
    <jaxb:globalBindings generateIsSetMethod="true" fixedAttributeAsConstantProperty="true">
        <xjc:serializable />
    </jaxb:globalBindings>
    <jaxb:bindings schemaLocation="myNormalSchema.xsd">
        <jaxb:bindings node="//xs:element[@name='ElementName']/xs:simpleType">
               <jaxb:typesafeEnumClass name="MyEnumType" />
        </jaxb:bindings>
   </jaxb:bindings>
</jaxb:bindings>

myNormalSchema.xsd

以下是根据您的问题进行逆向工程的示例 XML 架构:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
    targetNamespace="http://www.example.com" 
     xmlns="http://www.example.com" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="ElementName">
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:enumeration value="MY_ENUM_1"/>
                <xs:enumeration value="MY_ENUM_2"/>
            </xs:restriction>
        </xs:simpleType>
   </xs:element>

    <xs:element name="Root">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="ElementName"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

XJC 通话

xjc -extension -d out -b bindings.xml myNormalSchema.xsd

MyEnumType

其中一个生成的类是一个名为MyEnumType 的枚举。

package com.example;

import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlType;

@XmlType(name = "")
@XmlEnum
public enum MyEnumType 

    MY_ENUM_1,
    MY_ENUM_2;

    public String value() 
        return name();
    

    public static MyEnumType fromValue(String v) 
        return valueOf(v);
    


Root 类也是使用isSet 方法生成的:

package com.example;

import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = 
    "elementName"
)
@XmlRootElement(name = "Root")
public class Root
    implements Serializable


    @XmlElement(name = "ElementName", required = true)
    protected MyEnumType elementName;

    public MyEnumType getElementName() 
        return elementName;
    

    public void setElementName(MyEnumType value) 
        this.elementName = value;
    

    public boolean isSetElementName() 
        return (this.elementName!= null);
    


示例

http://bdoughan.blogspot.com/2011/05/schema-to-java-xmlmimetype.html http://bdoughan.blogspot.com/2011/04/xml-schema-to-java-xsd-choice.html

【讨论】:

我需要对所有此类元素进行绑定吗?有没有办法为所有受枚举限制的字符串切换此修改?我在提供的模式中有 287 次出现,我无法修改它们。 拯救了我的一天,但是驴子的巨大痛苦......应该有更好的方法。

以上是关于如何使用 JAXB 从 XML 模式生成 Java 枚举?的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的 Jaxb 等效项

java生成解析xml的另外两种方法JAXB

java生成解析xml的另外两种方法JAXB

JAXB:为啥在生成的 xml 文档中未使用定义的命名空间前缀?

JAXB java类与xml互转

Java操作XML的工具:JAXB