2013-07-03 36 views
6

XMLスキーマを表すPOJOのオブジェクトツリーがあります。これは、次のjaxb antスクリプトで作成されました。SAXParseException:値が 'date'の有効な値ではありません

私は属性が不足しているため、スキーマに対するルートPOJOとその子実体を検証します。 (試す/ SO How to validate against schema in JAXB 2.0 without marshalling?質問に触発省略catchブロック、)私の属性の

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; 

java.util.Dateオブジェクトから別のPOJO(HibernateにマップされているPOJO)からデータが取り込まれます。

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

を使用しています。時間部分を入力すると、時間部分がXMLに出力されます。

あなたが表現を上書きする@XmlSchemaTypeアノテーションを使用することができます:あなたは、対応するXML表現が何であるかを見るためにgetXMLSchemaType()メソッドを呼び出すことができます。以下

のJavaモデル(ルート)

XMLGregorianCalendar

3つのフィールドを持つオブジェクトです。 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

[OK]を、私は XmlGregorianCalendarsのlooooooooooooooooooooooooooooooooootsを持っているのでを追加するXJCを指示する方法がありますすべてのXGCにxmlSchemaType属性?スキーマ型は、すなわちxsd:dateまたはxsd:dateTime XMLスキーマ型でビルドのうちの1つである場合がありますが、これらのタイプの1つの拡張していないとき

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にすべてのXGCにxmlSchemaType属性を追加するよう指示する方法はありますか? –

0

日は '2001-05-11T00:00:00.000 + 02:00' の場合XMLGregorianCalendarプロパティの出力は、それを作成する方法に基づいて行われますデフォルトでは

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

申し訳ありません。私はスキーマを変更することはできません。相互運用性プロセスで使用される標準スキーマです。スキーマ自体は公開する必要がありますが、私はそれについての詳細情報を開示したくはありません –

関連する問題