JAXB:将元素类型xs:string绑定到Enum

时间:2015-10-02 03:13:11

标签: java xml enums jaxb

我的供应商为我提供了一个XSD,其元素定义为String。但是在他的规范中,他表示此字符串只能包含3个值中的1个:

例如:

<xs:complexType name="MitigationStatus">
  <xs:annotation>
    <xs:documentation>
      This represents a list of mitigation statuses.  Can be OPEN, CLOSED, INVALID 
    </xs:documentation>
  </xs:annotation>
  <xs:sequence>
    <xs:element name="status" minOccurs="0" maxOccurs="unbounded" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

我想在我的绑定文件中添加一些内容,以便在我解冻XML时,状态不是String,而是Enum

我找到的所有文档似乎都表明XSD要求String属于enum类型。

即使Enum不是XSD,有没有办法将字符串绑定到enum类型?

2 个答案:

答案 0 :(得分:2)

您可以使用下面指示的更改稍微修改XML架构中的此限制,并从中生成Java类。

<jaxb:bindings node="//xsd:complexType[@name='MitigationStatus']">
  <jaxb:bindings node="./xsd:element[@name='status']">
    <jaxb:property>
      <jaxb:baseType>
        <jaxb:javaType name="StatusImpl"
                       parseMethod="StatusImpl.parseStringToEnum"
                       printMethod="StatusImpl.printEnumToString"/>
      </jaxb:baseType>
    </jaxb:property>
  </jaxb:bindings>
</jaxb:bindings>

这将导致枚举类StatusType。在XML中,无论如何都是字符串,所以它保持原样。

如果您确实想通过绑定文件执行此操作,可以使用以下内容:

public class StatusImpl {
    public static StatusType parseStringToEnum( String value ){
        return StatusType.valueOf( value );
    }
    public static String printEnumToString( StatusType impl ){
        return impl.toString();
    }
}

假设枚举状态类型,类StatusImpl只是

apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'jacoco'
apply plugin: 'maven'

project.ext {
    springBootVersion = '1.1.7.RELEASE'
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}
buildscript {
    repositories {
        flatDir {
            dirs "$rootProject.projectDir/libs"
        }
        maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
        maven { url "http://repo.spring.io/libs-milestone" }
        maven { url "http://repo.spring.io/libs-snapshot" }
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE")
  testCompile('org.spockframework:spock-core:1.0-groovy-2.0') {
    exclude group: 'org.codehaus.groovy', module: 'groovy-all'
}

  testCompile('org.spockframework:spock-spring:1.0-groovy-2.0') {
    exclude group: 'org.spockframework', module: 'spock-core'
    exclude group: 'org.spockframework', module: 'spring-beans'
    exclude group: 'org.spockframework', module: 'spring-test'
    exclude group: 'org.codehaus.groovy', module: 'groovy-all'
}

   testCompile("org.springframework.boot:spring-boot-starter-test:$springBootVersion")
    testCompile('org.codehaus.groovy.modules.http-builder:http-builder:0.7+')
    testCompile("junit:junit")
    }
}

jacocoTestReport {
    group = "Reporting"
    description = "Generate Jacoco coverage reports after running tests."
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}

答案 1 :(得分:0)

我不知道你有什么问题,但以下工作正常。如您所见,没有XSD,只需手动编码JAXB类。

public class Test {
    public static void main(String[] args) throws Exception {
        String xml = "<Path>\r\n" +
                     "  <Direction>North</Direction>\r\n" +
                     "  <Direction>North</Direction>\r\n" +
                     "  <Direction>East</Direction>\r\n" +
                     "  <Direction>South</Direction>\r\n" +
                     "</Path>";
        JAXBContext jaxbContext = JAXBContext.newInstance(Path.class);
        Path path = (Path)jaxbContext.createUnmarshaller().unmarshal(new StringReader(xml));
        for (Direction dir : path.directions)
            System.out.println(dir);
    }
}
@XmlEnum
enum Direction {
    @XmlEnumValue("North") NORTH,
    @XmlEnumValue("South") SOUTH,
    @XmlEnumValue("East")  EAST,
    @XmlEnumValue("West")  WEST
}
@XmlRootElement(name = "Path")
class Path {
    @XmlElement(name = "Direction")
    List<Direction> directions = new ArrayList<>();
}

输出

NORTH
NORTH
EAST
SOUTH