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

时间:2011-05-10 23:42:58

标签: java xml jaxb

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

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

<SpecialValue>0x1234</SpecialValue>

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

<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类正确反映了这一点:

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

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

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

在这种情况下,整数0x1234(十进制4660)的字符串值为“4660”,不符合我的架构(因为它没有“0x”前缀)。

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

修改:根据已接受的答案,以下是我为此工作所做的工作:

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

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

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

<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>

3 个答案:

答案 0 :(得分:7)

非常相似的问题:“如何将字符串坐标映射到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>

(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);
    }
}

(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>

(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>

(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>();

答案 1 :(得分:5)

试试这个

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

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

答案 2 :(得分:0)

您需要自定义适配器。这是一篇处理自定义布尔结果的帖子,但也可以应用于您的场景。

此外,这里是JAXB的XmlAdapter的API文档: http://jaxb.java.net/nonav/2.1/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html

希望这有帮助!

相关问题