Java 如何指定JAXB用于封送/解封送数据的适配器?
有没有办法指定JAXB在我的XML模式中用于封送/解封送对象的适配器 例如,如果我想将以下内容解析为整数:Java 如何指定JAXB用于封送/解封送数据的适配器?,java,xml,jaxb,Java,Xml,Jaxb,有没有办法指定JAXB在我的XML模式中用于封送/解封送对象的适配器 例如,如果我想将以下内容解析为整数: <SpecialValue>0x1234</SpecialValue> 但是,当我想将值封送回XML元素(它是字符串文字)时,适配器类会执行以下操作: public String marshal(Integer value) { if (value == null) { return null; } return value
<SpecialValue>0x1234</SpecialValue>
但是,当我想将值封送回XML元素(它是字符串文字)时,适配器类会执行以下操作:
public String marshal(Integer value) {
if (value == null) {
return null;
}
return value.toString();
}
在本例中,整数0x1234(十进制为4660)的字符串值为“4660”,它不符合我的模式(因为它没有“0x”前缀)
如何告诉适配器希望将整数0x1234编组为“0x1234”字符串文字?我希望能够在模式中这样做,这样我就可以生成新的Java类,而不必修改输出。这可能吗
编辑:根据已接受的答案,以下是我为使其正常工作所做的:
我在com.example.Parse类中编写了一个名为toHexString()的方法:
然后我将我的模式指向该打印方法:
<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"/>
虽然我还没有测试过,但我记得使用了非常类似的东西。您需要一个自定义适配器。这里有一篇文章讨论了一个自定义布尔结果,但也可以应用到您的场景中 此外,以下是JAXB的XmlAdapter的API文档: 希望这有帮助 非常类似的问题:“如何将字符串坐标映射到java.awt.Point?” (0)模式
(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);
}
}
package com.kjcode.hexgrid.jaxbadapter;
导入java.awt.Point;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
公共类PointAdapter扩展了XmlAdapter{
@凌驾
公共点解组(字符串v)引发异常{
字符串[]坐标=v.split(“,”);
返回新的点(Integer.parseInt(coords[0]),Integer.parseInt(coords[1]);
}
@凌驾
公共字符串封送处理(第v点)引发异常{
返回字符串格式(“%d,%d”,v.x,v.y);
}
}
(2) 创建绑定文件。关键是要添加:
jaxb:extensionBindingPrefixes=“xjc”xmlns:xjc=”http://java.sun.com/xml/ns/jaxb/xjc"
(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>
com.sun.tools.xjc.maven2
maven jaxb插件
1.1.1
生成
com.kjcode.hexmap.api.logic.field.generated
真的
(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>();
公共类边界{
@XmlElement(必需=true)
保护字符串类型;
@XmlElement(必需=true)
受保护的字符串名称;
@XmlElement(必需=true,类型=String.class)
@XmlJavaTypeAdapter(PointAdapter.class)
受保护的列表点=新建LinkedList();
成功了。有关完整的详细信息,请参见我上面的编辑。谢谢。@BlueInteger.toHexString()
不起作用?它是一个内置的方法,可以做到这一点。卡罗尔:您知道如何让适配器为java.util.List
执行封送和解封送吗?请注意
接受xmlType=“xyz”
,模式中的“列表”用maxOccurance=unbounded
表示,而不是实际的模式类型。@Malvon Java List只是简单地转换为xml列表,反之亦然,如果它是“泛型的”类型有适配器或是标准类型。上面的示例显示了如何整理/取消整理点列表。JAXB运行时确实正确处理了list
,但是,在我的例子中,应用程序检索数据的方式是,这些list
首先实例化,如果有数据,则填充它们。如果没有,则返回作为一个空的列表
。因此,我需要某种机制,即XmlAdapter,来访问这些结构并检查它们是否为空。即使我扩展XmlAdapter
,我也必须有一种方法全局地告诉几百个架构文档在编组时执行此检查。在这种情况下,什么是他xmlType
?xs:any?如何将绑定文件添加到pom中?
<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>
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);
}
}
<?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>
<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>
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>();