我正在尝试创建 XmlAdapter
,它接收 XMLGregorianCalendar
并输出 XMLGregorianCalendar
. 目的是简单地在解组数据时从元素中删除时区数据 .
它看起来像这样:
public class TimezoneRemoverAdapter extends XmlAdapter<XMLGregorianCalendar, XMLGregorianCalendar> {
public XMLGregorianCalendar unmarshal(XMLGregorianCalendar xgc) {
if(xgc == null) {
return null;
}
xgc.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
return xgc;
}
public XMLGregorianCalendar marshal(XMLGregorianCalendar xgc) {
return xgc;
}
}
这适用于以下代码:
public class FooElement {
@XmlElement(name="bar-date")
@XmlJavaTypeAdapter(TimezoneRemoverAdapter.class)
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar barDate;
}
不幸的是,当我使用 jaxb-bindings.xml
文件生成代码时,上面的代码如下所示:
public class FooElement {
@XmlElement(name="bar-date", type=java.lang.String.class)
@XmlJavaTypeAdapter(TimezoneRemoverAdapter.class)
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar barDate;
}
它将类型设置为 String
,因此我的上述方法不起作用 . 类型 String
设置将覆盖它应该的 XMLGregorianCalendar
类型 . 我可以手动更改它,但是'd rather not have to remember to update it every time the jaxb files are regenerated. Does anyone know if there'是一个手动设置 @XmlElement
类型或忽略它的选项?
以下是 jaxb-bindings.xml
文件的相关部分:
<jxb:bindings node=".//xs:element[@name=bar-date]">
<jxb:property>
<jxb:baseType>
<jxb:javaType name="javax.xml.datatype.XMLGregorianCalendar" adapter="foo.bar.TimezoneRemoverAdapter" />
</jxb:baseType>
</jxb:property>
</jxb:bindings>
2 回答
更新
总结:
您有一个在某处使用日期样式的模式,您无法更改模式
你有一些使用该模式的XML数据,并用时区指定一些日期(所以它是
yyyy-MM-ddXXX
格式)您要从该文件中日期的 representation 删除
XXX
部分(日期本身不发送任何时区,日期只是一个数字)所以这可能是一个示例模式:
这可能是一个示例数据:
这是JAXB注释类
这是日期适配器
这是主要的,验证模式:
这是输出,时区已被删除,日期表示已明显改变
也许这个日期表示更改不是您所期望的,但这不是JAXB关注的问题,所代表的日期没有改变 .
我忘了绑定反向生成Foo:
更新结束
对不起,评论太久了......
我无法理解:
你为什么要用
XmlGregorianCalendar
?为什么你要
marshal
/unmarshal
(serialize
/deserialize
)才能使用相同的数据结构?为什么要删除时区?
和
我用直而简单的
java.util.Date
marshal
/unmarshal
应始终涉及String
(至少对于XML)我真的没有理由任意删除一个日期表示 . 也许你想以绝对的方式序列化它 .
然而
在您的情况下,您必须以不同的方式指定java类型:
它适用于我,我做了类似的更多适配器:
我把上面的绑定作为
globalBindings
放在一个扩展名为.xjb
的不同文件中,并且我在需要的地方使用它 .