有没有办法指定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>
答案 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
希望这有帮助!