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

tro*_*yal 9 java xml jaxb

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

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

<SpecialValue>0x1234</SpecialValue>
Run Code Online (Sandbox Code Playgroud)

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

<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" />
Run Code Online (Sandbox Code Playgroud)

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

public Integer unmarshal(String value) {
    return (Integer.decode(value));
}
Run Code Online (Sandbox Code Playgroud)

但是,当我想将值封送回XML元素(String字面值)时,Adapter类执行以下操作:

public String marshal(Integer value) {
    if (value == null) {
        return null;
    }
    return value.toString();
}
Run Code Online (Sandbox Code Playgroud)

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

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

编辑:根据接受的答案,这是我做的工作:

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

public static String toHexString(int value)
{
    return ("0x" + Integer.toHexString(value));
}
Run Code Online (Sandbox Code Playgroud)

然后我将模式指向该方法进行打印:

<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>
Run Code Online (Sandbox Code Playgroud)

Kar*_*ról 8

非常相似的问题:"如何将字符串坐标映射到java.awt.Point?"

(0)架构

<xsd:simpleType name="Point">
    <xsd:restriction base="xsd:string">
        <xsd:pattern value="([0-9])+,([0-9])+" />
    </xsd:restriction>
</xsd:simpleType>

<xsd:complexType name="HexAreaBorder">
    <xsd:sequence minOccurs="1" maxOccurs="1">
        <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string" />
        <xsd:element minOccurs="1" maxOccurs="1" name="name" type="xsd:string" />
        <xsd:element name="points" type="Point" minOccurs="1" maxOccurs="unbounded" />
    </xsd:sequence>
</xsd:complexType>
Run Code Online (Sandbox Code Playgroud)

(1)创建扩展XmlAdapter的适配器类.

package com.kjcode.hexgrid.jaxbadapter;
import java.awt.Point;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class PointAdapter extends XmlAdapter<String, Point> {

    @Override
    public Point unmarshal(String v) throws Exception {
        String[] coords = v.split(",");
        return new Point(Integer.parseInt(coords[0]), Integer.parseInt(coords[1]));
    }

    @Override
    public String marshal(Point v) throws Exception {
        return String.format("%d,%d", v.x, v.y);
    }
}
Run Code Online (Sandbox Code Playgroud)

(2)创建绑定文件.关键是添加:jaxb:extensionBindingPrefixes ="xjc"xmlns:xjc ="http://java.sun.com/xml/ns/jaxb/xjc"

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    jaxb:extensionBindingPrefixes="xjc" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    xmlns="hexmap" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    jaxb:version="2.1">

    <jaxb:bindings schemaLocation="hexmap.xsd">
        <jaxb:globalBindings>
            <xjc:javaType adapter="com.kjcode.hexgrid.jaxbadapter.PointAdapter" name="java.awt.Point" xmlType="Point" />
        </jaxb:globalBindings>
    </jaxb:bindings>
</jaxb:bindings>
Run Code Online (Sandbox Code Playgroud)

(3)配置pom.xml

<plugin>
    <groupId>com.sun.tools.xjc.maven2</groupId>
    <artifactId>maven-jaxb-plugin</artifactId>
    <version>1.1.1</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <generatePackage>com.kjcode.hexmap.api.logic.field.generated</generatePackage>
        <extension>true</extension>
    </configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)

(4)JAXB将生成

public class HexAreaBorder {

    @XmlElement(required = true)
    protected String type;
    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true, type = String.class)
    @XmlJavaTypeAdapter(PointAdapter.class)
    protected List<Point> points = new LinkedList<Point>();
Run Code Online (Sandbox Code Playgroud)


Bal*_*a R 6

试试这个

<jaxb:javaType name="int" parseMethod="Integer.decode" 
                          printMethod="Integer.toHexString"/>
Run Code Online (Sandbox Code Playgroud)

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