JAXB中不区分大小写的XMLEnumValue

时间:2014-07-29 07:39:30

标签: java xml enums jaxb

JAXB允许使用@XMLEnum注释从XML直接定位Enum实例。 在查找@XMLEnumValue的值时,JAXB似乎区分大小写。

但是我遇到了一个问题,我需要以不区分大小写的方式找到Enum实例。 JAXB是否以某种方式提供此功能? 如果没有这个,我会坚持使用手动找到Enum常量。

我可以使用XMLAdapter,但为每个创建的枚举维护适配器变得非常繁琐。

编辑:

  

为什么必须以不区分大小写的方式找到枚举?

因为我使用xml来读取系统的配置,所以我不希望用户被限制在固定的情况下。我希望能回答你的问题。

public class CaseInsensitiveEnumAdapter<E extends Enum<E>> extends XmlAdapter<String, E> {

    private final Class<E> clazz;

    public CaseInsensitiveEnumAdapter(Class<E> clazz) {
        this.clazz = clazz;
    }

    @Override
    public E unmarshal(String v) throws Exception {
        return Enum.<E>valueOf(clazz, v.toUpperCase().trim());
    }

    @Override
    public String marshal(E v) throws Exception {
        return v.name();
    }
}

由于我需要.class作为枚举,我必须为所有枚举创建单独的适配器。

1 个答案:

答案 0 :(得分:1)

请纳伦德拉先生

我想出了一个基于正则表达式的解决方案。 这个想法是将模式限制与能够接受任何大小写组合的正则表达式一起使用。 我创建了一个示例,其中列举了三种颜色:绿色,红色和蓝色。 以下常规异常将接受“ GrEEn ”和“ gReeN ”文字作为有效值:

g|Gr|Re|Ee|En|N

在示例文件下:

示例XML架构

<xs:simpleType name="ColorType" final="restriction" >
    <xs:restriction base="xs:string">
        <xs:pattern value="g|Gr|Re|Ee|En|N" />
        <xs:pattern value="r|Re|Ed|D" />
        <xs:pattern value="b|Bl|Lu|Ue|E" />
    </xs:restriction>
</xs:simpleType>
<xs:element name="SomeElement">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Color" type="ColorType" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

XML案例1

<SomeElement>
    <Color>GreEN</Color>
</SomeElement>

XML案例2

<SomeElement>
    <Color>gREen</Color>
</SomeElement>

JUnit

public class TestJaxb {

    private static final String GREEN = "GREEN";

    @Test
    public void shouldParseCase1() throws JAXBException, MalformedURLException {
        URL xmlUrl = // Load XML file 1
        SomeElement someElement = parse(xmlUrl, SomeElement.class);
        assertEquals(GREEN, someElement.getColor().toUpperCase());
    }

    @Test
    public void shouldParseCase2() throws JAXBException, MalformedURLException {
        URL xmlUrl = // Load XML file 2
        SomeElement someElement = parse(xmlUrl, SomeElement.class);
        assertEquals(GREEN, someElement.getColor().toUpperCase());
    }

    private <T> T parse(URL url, Class<T> clazz) throws JAXBException {
        Unmarshaller unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
        return clazz.cast(unmarshaller.unmarshal(url));
    }
}

我意识到,这会使XSD规范的用户更难以理解枚举中允许使用哪些值,但是注释可能就足够了。

事实是,我发现没有其他方法可以在不实际更改JAXB代码的情况下实现这一目标。

希望这会有所帮助。

最诚挚的问候