如何指定 JAXB 用于编组/解组数据的适配器?

2022-01-19 00:00:00 xml java jaxb

有没有办法指定 JAXB 用于在我的 XML 模式中编组/取消编组对象的适配器?

Is there a way to specify the Adapter which JAXB uses for marshaling/unmarshaling objects in my XML schema?

例如,如果我想将以下内容解析为整数:

For example, if I want to parse the following as an integer:

<SpecialValue>0x1234</SpecialValue>

我可以在我的架构中使用以下内容:

I can use the following in my schema:

<xs:simpleType name="HexInt">
    <xs:annotation> 
        <xs:appinfo>
            <jaxb:javaType name="int" parseMethod="Integer.decode" />
        </xs:appinfo>
    </xs:annotation>  
    <xs:restriction base="xs:string">
        <xs:pattern value="0x[0-9a-fA-F]+" />
    </xs:restriction>
</xs:simpleType>
<xs:element name="SpecialValue" type="HexInt" />

当我通过 XJC 工具运行架构时,字符串0x1234"应该使用 Integer.decode() 解码为整数,值为 0x1234,或十进制的 4660.生成的 Adapter 类正确反映了这一点:

When I run the schema through the XJC tool, the String "0x1234" should be decoded using Integer.decode() as the Integer with value 0x1234, or 4660 in decimal. The Adapter class that is generated reflects this properly:

public Integer unmarshal(String value) {
    return (Integer.decode(value));
}

但是,当我想将值编组回 XML 元素(它是一个字符串字面量)时,Adapter 类会执行以下操作:

However, when I want to marshal the value back to an XML element (which is a String literal), the Adapter class does the following:

public String marshal(Integer value) {
    if (value == null) {
        return null;
    }
    return value.toString();
}

在这种情况下,整数 0x1234(十进制的 4660)的 String 值是4660",这不符合我的架构(因为它没有0x"前缀).

In this case, the String value of the integer 0x1234 (4660 in decimal) is "4660", which does not adhere to my schema (because it has no "0x" prefix).

如何告诉适配器我希望将整数 0x1234 编组为0x1234"字符串文字?我希望能够在模式中执行此操作,这样我就可以生成新的 Java 类而无需修改输出.这可能吗?

How can I tell the Adapter that I want the integer 0x1234 to be marshalled as the "0x1234" String literal? I would be like to be able to do this within the schema so that I can just generate new Java classes without having to modify the output. Is this possible?

根据接受的答案,这是我为使其正常工作所做的工作:

Based on the accepted answer, here is what I did to get this working:

我在 com.example.Parse 类中编写了一个名为 toHexString() 的方法:

I wrote a method in a class com.example.Parse called toHexString():

public static String toHexString(int value)
{
    return ("0x" + Integer.toHexString(value));
}

然后我将我的架构指向该打印方法:

Then I pointed my schema to that method for printing:

<xs:simpleType name="HexInt">
    <xs:annotation> 
        <xs:appinfo>
            <jaxb:javaType name="int" parseMethod="Integer.decode" printMethod="com.example.Parse.toHexString" />
        </xs:appinfo>
    </xs:annotation>  
    <xs:restriction base="xs:string">
        <xs:pattern value="0x[0-9a-fA-F]+" />
    </xs:restriction>
</xs:simpleType>

推荐答案

试试这个

<jaxb:javaType name="int" parseMethod="Integer.decode" 
                          printMethod="Integer.toHexString"/>

虽然我还没有测试过,但我记得使用过非常相似的东西.

I haven't tested it though but I remember using something very similar.

相关文章