Java JAXB中不区分大小写的XMLEnumValue
JAXB允许使用Java JAXB中不区分大小写的XMLEnumValue,java,xml,enums,jaxb,Java,Xml,Enums,Jaxb,JAXB允许使用@XMLEnum注释从XML直接定位枚举实例。 在从@XMLEnumValue查找值时,JAXB似乎区分大小写 但我面临一个问题,需要以不区分大小写的方式定位Enum实例。JAXB是否以某种方式提供了此功能? 没有这一点,我只能手动查找枚举常量 我可以为此使用XMLAdapter,但是为创建的每个枚举维护一个适配器会变得非常繁琐 编辑: 为什么必须以不区分大小写的方式定位枚举 因为我使用xml来读取系统的配置,我不希望用户被限制在固定的情况下。我希望这能回答你的问题 public
@XMLEnum
注释从XML直接定位枚举实例。
在从@XMLEnumValue
查找值时,JAXB似乎区分大小写
但我面临一个问题,需要以不区分大小写的方式定位Enum实例。JAXB是否以某种方式提供了此功能?
没有这一点,我只能手动查找枚举常量
我可以为此使用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();
}
}
公共类CaseInsensitiveEnumAdapter扩展了XmlAdapter{
私人期末班;
公共案件不敏感适应者(班级){
this.clazz=clazz;
}
@凌驾
public E unmarshal(字符串v)引发异常{
返回Enum.valueOf(clazz,v.toUpperCase().trim());
}
@凌驾
公共字符串封送处理(EV)引发异常{
返回v.name();
}
}
由于我需要枚举的.class
,我必须为所有枚举创建单独的适配器。善良的Narendra先生
我提出了一个基于正则表达式的解决方案。
其思想是使用模式限制和能够接受任何大小写组合的正则表达式。
我创建了一个例子,列举了三种颜色:绿色、红色和蓝色。
以下常规异常将接受“绿色”和“绿色”文本作为有效值:
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));
}
}
公共类TestJaxb{
私有静态最终字符串GREEN=“GREEN”;
@试验
public void shouldParseCase1()引发JAXBEException,MalformedUrlexException{
URL xmlUrl=//加载XML文件1
SomeElement SomeElement=parse(xmlUrl,SomeElement.class);
assertEquals(绿色,someElement.getColor().toUpperCase());
}
@试验
public void shouldParseCase2()引发JAXBEException,MalformedUrlexException{
URL xmlUrl=//加载XML文件2
SomeElement SomeElement=parse(xmlUrl,SomeElement.class);
assertEquals(绿色,someElement.getColor().toUpperCase());
}
private T parse(URL,Class clazz)抛出jaxbeexception{
Unmarshaller Unmarshaller=JAXBContext.newInstance(clazz.createUnmarshaller();
返回clazz.cast(unmarshaller.unmarshal(url));
}
}
我意识到这使得XSD规范的用户更难理解枚举中允许哪些值,但也许一条注释就足够了
事实上,我发现没有其他方法可以在不改变JAXB代码的情况下实现这一点
希望这有帮助
致以最诚挚的问候为什么您必须以不区分大小写的方式查找枚举?@JamesB我已更新帖子以回答您的问题。如果用户没有被迫输入区分大小写的数据,您能否轻松识别XML文本内容中的枚举?如果是这样的话,您可以在将其提供给JAXB之前将其转换为大写?你能发布这段代码吗?我相信这在JAXB中是不可能的。我想这是不可能的实际原因-这将是有问题的编组。对于枚举:
public enum DayOfWeek{MONDAY}
。这在解组期间是可以的,所以“星期一”、“星期一”、“星期一”都可以分解为星期一。在编组时,将出现一个问题,即它将编组到什么“版本”。也许可以实现一个为编组提供默认值的实现。但是我不知道在JAXB中有什么解决这个问题的方法。我想你对这个问题有点误解了。问题是如何实现@Xml…
注释bean,从包含枚举值的Xml反序列化,该值的大小与实际枚举常量不同。Hello@SteffenHarbich在问题的注释中,有人已经说过这不可行,所以我提出了另一个想法来实现用户真正需要的内容这是不区分大小写的解组。好的,基本上你做了一个toUpperCase
,至少对我来说,这是已知的工作。我开始赏金是因为我认为在过去的5年里可能会有一个新的功能或者其他什么问题。但不幸的是,似乎不是这样,事实并非如此,没有XSD中的模式,当XML输入与硬编码模式版本的大小写不同时,XJC编译器将无法解组。我认为我可以在JAXB中实现这样一个特性,但我没有研究它,所以我不知道实际的复杂性。很抱歉,这更像是OP的工作,甚至没有注意到线程日期:D干杯!