java 如何指定 JAXB 用于编组/解组数据的适配器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5957708/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I specify the adapter(s) which JAXB uses for marshaling/unmarshaling data?
提问by troyal
Is there a way to specify the Adapter which JAXB uses for marshaling/unmarshaling objects in my XML schema?
有没有办法指定 JAXB 用于在我的 XML 模式中编组/解组对象的适配器?
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" />
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:
当我通过 XJC 工具运行模式时,应该使用 Integer.decode() 作为值为 0x1234 或十进制 4660 的整数解码字符串“0x1234”。生成的 Adapter 类正确地反映了这一点:
public Integer unmarshal(String value) {
return (Integer.decode(value));
}
However, when I want to marshal the value back to an XML element (which is a String literal), the Adapter class does the following:
但是,当我想将值编组回 XML 元素(它是一个字符串文字)时,Adapter 类会执行以下操作:
public String marshal(Integer value) {
if (value == null) {
return null;
}
return value.toString();
}
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(十进制为 4660)的字符串值是“4660”,它不符合我的架构(因为它没有“0x”前缀)。
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?
我如何告诉适配器我希望将整数 0x1234 编组为“0x1234”字符串文字?我希望能够在模式中执行此操作,以便我可以生成新的 Java 类而无需修改输出。这可能吗?
Edit:Based on the accepted answer, here is what I did to get this working:
编辑:根据接受的答案,这是我为使其正常工作所做的工作:
I wrote a method in a class com.example.Parse called toHexString():
我在 com.example.Parse 类中编写了一个名为 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>
采纳答案by Bala R
Try this
试试这个
<jaxb:javaType name="int" parseMethod="Integer.decode"
printMethod="Integer.toHexString"/>
I haven't tested it though but I remember using something very similar.
我还没有测试过,但我记得使用了非常相似的东西。
回答by Karol Król
Very similar problem: "How to map String coordinates to java.awt.Point ?"
非常相似的问题:“如何将 String 坐标映射到 java.awt.Point ?”
(0) Schema
(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) Create adapter class that extends XmlAdapter.
(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) Create bindings file. The key is to add: jaxb:extensionBindingPrefixes="xjc" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
(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) Configure pom.xml
(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 will generate
(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>();
回答by Geoff
You want a custom Adapter. Here's a post that deals with a custom boolean result, but could be applied to your scenario as well.
您需要一个自定义适配器。这是一篇处理自定义布尔结果的帖子,但也可以应用于您的场景。
In addition, here's the API documentation for JAXB's XmlAdapter: http://jaxb.java.net/nonav/2.1/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html
此外,这里是 JAXB 的 XmlAdapter 的 API 文档:http://jaxb.java.net/nonav/2.1/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html
Hope this helps!
希望这可以帮助!