2013-07-03 121 views
6

有效值我的POJO的對象樹表示XML架構。這是用以下jaxb ant腳本創建的。的SAXParseException:值不是「日期」

我想根據模式驗證根POJO及其子實體缺少的屬性。

我的代碼如下:(試行/省略catch塊,靈感來自SO質疑How to validate against schema in JAXB 2.0 without marshalling?

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; 
} 

我的一個屬性(pojo.childEntity.someAttribute)是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; 

它從來自另一POJO(一個是與Hibernate映射)一個java.util.Date對象進行填充。

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; 
    } 

} 

唯一的例外是:

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'.] 

這看起來像JAXB試圖設置日期和時間必須只攜帶日期字段,XMLGregorianCalendard是一個簡單的日期時間的容器。

的問題是:是什麼原因造成的錯誤?怎麼修?

回答

2

默認情況下爲XMLGregorianCalendar屬性輸出將根據你如何創建它。如果填充時間部分,則時間部分將輸出爲XML。您可以撥打getXMLSchemaType()方法來查看相應的XML表示是什麼:

可以使用@XmlSchemaType註釋覆蓋表示。

的Java模型(根)

下面是用3個XMLGregorianCalendar字段的對象。 3日我將使用一個@XmlSchemaType批註指定的架構類型。

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; 

} 

演示代碼

在演示代碼下面我們將創建的XMLGregorianCalendar 2個實例。一個會有架構類型date另一個dateTime。默認情況下,這是編組XML時使用的XML表示。在schemaTypeDate字段中,我們將使用@XmlSchemaType註釋來覆蓋默認值。

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); 
    } 

} 

輸出

<?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

好了,因爲我的 XmlGregorianCalendars loooooooooooooooooooooooooooooooooots有沒有辦法告訴XJC添加 xmlSchemaType屬性到所有XGC?

當架構類型是XML Schema類型即xsd:datexsd:dateTime構建的一個,但不是當你擴展了這些類型之一JAXB會爲你做這個。

XML架構(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> 

@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; 

} 
+0

事實更復雜(我認爲這並不重要):我從日期填充GregCalendar –

+0

@djechelon - 我已經更新了我的答案應該有所幫助的信息。 –

+0

好吧,因爲我有XmlGregorianCalendars的loooooooooooooooooooooooooooooooooots有沒有辦法告訴XJC添加xmlSchemaType屬性到所有的XGC? –

0

如果日期是 '2001-05-11T00:00:00.000 + 02:00' 使用

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

對不起。我無法更改架構。它是互操作性過程中使用的標準模式。模式本身*應該是公開的,但我不願意公開更多關於它的信息 –

相關問題