JAXB Bindings file Sets @XmlElement type à String au lieu de XMLGregorianCalendar
j'essaie de créer un XmlAdapter
qui prend un XMLGregorianCalendar
et sorties XMLGregorianCalendar
. Le but est de supprimer simultanément les données de fuseau horaire de l'élément lors de la désactivation des données.
Il ressemble à ceci:
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;
}
}
Cela fonctionne très bien pour le code suivant:
public class FooElement {
@XmlElement(name="bar-date")
@XmlJavaTypeAdapter(TimezoneRemoverAdapter.class)
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar barDate;
}
malheureusement, quand je génère le code en utilisant un jaxb-bindings.xml
le fichier, le code ci-dessus ressemble à ceci:
public class FooElement {
@XmlElement(name="bar-date", type=java.lang.String.class)
@XmlJavaTypeAdapter(TimezoneRemoverAdapter.class)
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar barDate;
}
il met le type à String
donc ma méthode ci-dessus ne fonctionne pas. Le type String
paramètre est primordial XMLGregorianCalendar
tapez ce que ça devrait être. Je peux le changer manuellement, mais je préfère ne pas avoir à le mettre à jour chaque fois que les fichiers jaxb sont régénérés. Est-ce que quelqu'un sait s'il y a une option pour définir manuellement le @XmlElement
tapez ou avez-vous ignoré?
Voici la partie pertinente du jaxb-bindings.xml
fichier:
<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 réponses
UPDATE
résumer:
- vous avez un schéma qui utilise le style date quelque part, et vous ne pouvez pas changer le schéma
- vous avez des données XML qui utilisent ce schéma et spécifiez une date avec timezone (donc c'est
yyyy-MM-ddXXX
format) - vous souhaitez supprimer le
XXX
partie de l' représentation de la date dans ce fichier (la date elle-même n'expédie aucun fuseau horaire, la date n'est qu'un nombre)
donc, cela pourrait être un exemple de schéma:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<element name="foo">
<complexType>
<sequence>
<element name="bar" type="date" minOccurs="1" maxOccurs="1"/>
</sequence>
</complexType>
</element>
</schema>
cela pourrait être un exemple de données:
<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="foo.xsd">
<bar>2014-01-01+06:00</bar>
</foo>
c'est JAXB annotated class
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo implements Serializable
{
private static final long serialVersionUID = 1L;
@XmlElement(name = "bar")
@XmlJavaTypeAdapter(DateAdapter.class)
@XmlSchemaType(name = "date")
private Date bar;
// getters/setters
}
ceci est un adaptateur de date
public class DateAdapter extends XmlAdapter<String, Date>
{
@Override
public String marshal(Date date)
{
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df.format(date);
}
@Override
public Date unmarshal(String date) throws ParseException
{
DateFormat df = new SimpleDateFormat("yyyy-MM-ddXXX");
return df.parse(date);
}
}
c'est le principal, de la validation par rapport au schéma:
public static void main(String[] args) throws JAXBException, SAXException
{
JAXBContext context = JAXBContext.newInstance(Foo.class);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(Foo.class.getResource("/foo.xsd"));
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setSchema(schema);
Foo foo = (Foo) unmarshaller.unmarshal(Foo.class.getResource("/foo.xml"));
System.out.println("unmarshalled: " + foo.getBar());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "foo.xsd");
marshaller.setSchema(schema);
marshaller.marshal(foo, System.out);
}
et c'est la sortie, le fuseau horaire a été supprimé et la représentation de la date a évidemment changé
unmarshalled: Tue Dec 31 19:00:00 CET 2013
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="foo.xsd">
<bar>2013-12-31</bar>
</foo>
peut-être cette date représentation le changement n'est pas ce à quoi vous vous attendiez, mais ce n'est pas une préoccupation de JAXB, la date représentée n'a pas changé.
j'oubliais les fixations pour inverser la génération de Foo:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.0">
<jaxb:globalBindings>
<xjc:javaType name="java.util.Date" xmlType="xsd:date" adapter="aaa.DateAdapter" />
</jaxb:globalBindings>
</jaxb:bindings>
FIN DE LA MISE À JOUR
désolé, trop long pour un commentaire...
je ne comprends pas:
- pourquoi diable utilisez-vous