SAXParseException: value is not a valid value for 'date'

I have a POJO object tree that is an XML Schema. This was created using jaxb ant script.

I want to check the root POJOs and its children on a schema for missing attributes.

My code is as follows: (try / catch block omitted, inspired by SO question How to check the correctness of the circuit in JAXB 2.0 without sorting? )

 public boolean validateAgainstSchema(Pojo pojo) { JAXBContext jc; jc = JAXBContext.newInstance(Pojo.class); SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = sf.newSchema(new ClassPathResource("schema.xsd").getFile()); Marshaller marshaller = jc.createMarshaller(); marshaller.setSchema(schema); marshaller.marshal(schema, new DefaultHandler()); return true; } 

One of my attributes ( pojo.childEntity.someAttribute ) is date

Xsd

 <xsd:attribute name="some_date" use="required"> <xsd:simpleType> <xsd:restriction base="xsd:date" /> </xsd:simpleType> </xsd:attribute> 

Java

 @XmlAttribute(name = "someDate", required = true) protected XMLGregorianCalendar someDate; 

It is populated from the java.util.Date object from another POJO (the one that maps to Hibernate).

 private static final XMLGregorianCalendar dateToCalendar(Date date) { if (date == null) return null; try { GregorianCalendar c = new GregorianCalendar(); c.setTime(date); return DatatypeFactory.newInstance() .newXMLGregorianCalendar(c); } catch (DatatypeConfigurationException e) { e.printStackTrace(); return null; } } 

The exception is:

 javax.xml.bind.MarshalException - with linked exception: [org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: '2001-05-11T00:00:00.000+02:00' is not a valid value for 'date'.] 

It looks like JAXB is trying to set the date and time for the field, which should only contain the date, and XMLGregorianCalendard is just a datetime container.

Question: what causes the error? How to fix?

+6
source share
2 answers

By default, the output for the XMLGregorianCalendar property will be based on how you create it. If you fill in the time part, then part of the time will be output in XML. You can call the getXMLSchemaType() method to find out what the corresponding XML representation is:

You can use the @XmlSchemaType annotation to override the view.

Java Model (Root)

Below is an object with fields 3 XMLGregorianCalendar . In the third, I will use the @XmlSchemaType annotation to indicate the type of schema.

 import javax.xml.bind.annotation.*; import javax.xml.datatype.XMLGregorianCalendar; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Root { protected XMLGregorianCalendar default1; protected XMLGregorianCalendar default2; @XmlSchemaType(name="date") protected XMLGregorianCalendar schemaTypeDate; } 

Demo code

In the demo code below we will create 2 instances of XMLGregorianCalendar . One will have a date type schema of another dateTime . By default, this is the XML representation used when sorting XML. In the schemaTypeDate field schemaTypeDate we will use the @XmlSchemaType annotation to override the default value.

 import javax.xml.bind.*; import javax.xml.datatype.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); DatatypeFactory df = DatatypeFactory.newInstance(); XMLGregorianCalendar date = df.newXMLGregorianCalendar("2013-07-03"); XMLGregorianCalendar dateTime = df.newXMLGregorianCalendar("1999-12-31T23:59:00"); Root root = new Root(); root.default1 = date; root.default2 = dateTime; root.schemaTypeDate = dateTime; Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(root, System.out); } } 

Output

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <root> <default1>2013-07-03</default1> <default2>1999-12-31T23:59:00</default2> <schemaTypeDate>1999-12-31</schemaTypeDate> </root> 

UPDATE

Ok, since I have looooooooooooooooooooooooooooooooooootoots XmlGregorianCalendars is there a way to tell XJC to add xmlSchemaType for all XGCs?

JAXB will do this for you when a schema type is one of the constructs in XML schema types, i.e. xsd:date or xsd:dateTime , but not when you extended one of these types.

XML Schema (schema.xsd)

 <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema"> <complexType name="root"> <sequence> <element name="dateElement" type="date" /> <element name="dateTimeElement" type="dateTime" /> <element name="extendedDateElement"> <simpleType> <restriction base="date" /> </simpleType> </element> </sequence> <attribute name="dateAttribute" type="date" /> <attribute name="dateTimeAttribute" type="dateTime" /> <attribute name="extendedDateAttribute"> <simpleType> <restriction base="date" /> </simpleType> </attribute> </complexType> </schema> 

Root

 @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "root", propOrder = { "dateElement", "dateTimeElement", "extendedDateElement" }) public class Root { @XmlElement(required = true) @XmlSchemaType(name = "date") protected XMLGregorianCalendar dateElement; @XmlElement(required = true) @XmlSchemaType(name = "dateTime") protected XMLGregorianCalendar dateTimeElement; @XmlElement(required = true) protected XMLGregorianCalendar extendedDateElement; @XmlAttribute(name = "dateAttribute") @XmlSchemaType(name = "date") protected XMLGregorianCalendar dateAttribute; @XmlAttribute(name = "dateTimeAttribute") @XmlSchemaType(name = "dateTime") protected XMLGregorianCalendar dateTimeAttribute; @XmlAttribute(name = "extendedDateAttribute") protected XMLGregorianCalendar extendedDateAttribute; } 
+2
source

If the date 2001-05-11T00: 00: 00.000 + 02: 00 'is used

 <xsd:restriction base="xsd:dateTime" /> 
0
source

Source: https://habr.com/ru/post/948611/


All Articles