java SAXParseException: 值不是“日期”的有效值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17444810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SAXParseException: value is not a valid value for 'date'
提问by usr-local-ΕΨΗΕΛΩΝ
I have an object tree of POJOs that represents an XML Schema. This was created with the following jaxb
ant script.
我有一个代表 XML 模式的 POJO 对象树。这是使用以下jaxb
ant 脚本创建的。
I want to validate the root POJO and its children entities against the schema for missing attributes.
我想针对缺失属性的模式验证根 POJO 及其子实体。
My code is the following: (try/catch block omitted, inspired by SO question How to validate against schema in JAXB 2.0 without marshalling?)
我的代码如下:(省略了 try/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;
}
One of my attributes (pojo.childEntity.someAttribute
) is a date
我的一个属性 ( pojo.childEntity.someAttribute
) 是date
XSD
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 gets populate from a java.util.Date
object from another POJO (one that is mapped with Hibernate).
它java.util.Date
从另一个 POJO(一个与 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'.]
This looks like JAXB tries to set both date and time for a field that must carry only the date, and XMLGregorianCalendard is simply a datetime container.
这看起来像 JAXB 试图为必须只包含日期的字段设置日期和时间,而 XMLGregorianCalendard 只是一个日期时间容器。
The question is: what causes the error? How to fix?
问题是:是什么导致了错误?怎么修?
采纳答案by bdoughan
By default the output for an XMLGregorianCalendar
property will be based on how you create it. If you populate the time portion, then the time portion will be output to XML. You can call the getXMLSchemaType()
method to see what the corresponding XML representation is:
默认情况下,XMLGregorianCalendar
属性的输出将基于您创建它的方式。如果填充时间部分,则时间部分将输出到 XML。您可以调用该getXMLSchemaType()
方法来查看对应的 XML 表示形式是什么:
You can use the @XmlSchemaType
annotation to override the representation.
您可以使用@XmlSchemaType
注释来覆盖表示。
Java Model (Root)
Java 模型(根)
Below is an object with 3 XMLGregorianCalendar
fields. On the 3rd I will use an @XmlSchemaType
annotation to specify the schema type.
下面是一个具有 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;
}
Demo Code
演示代码
In the demo code below we will create 2 instances of XMLGregorianCalendar
. One will have schema type date
the other dateTime
. By default this is the XML representation used when marshalling to XML. On the schemaTypeDate
field we will use the @XmlSchemaType
annotation to override the default.
在下面的演示代码中,我们将创建 2 个XMLGregorianCalendar
. 一个将具有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);
}
}
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 loooooooooooooooooooooooooooooooooots of XmlGregorianCalendars is there a way to tell XJC to add the xmlSchemaType attribute to all XGCs?
好的,既然我有 looooooooooooooooooooooooooooooooooots 的 XmlGregorianCalendars 有没有办法告诉 XJC 将 xmlSchemaType 属性添加到所有 XGC?
JAXB will do this for you when the schema type is one of the build in XML Schema types i.e. xsd:date
or xsd:dateTime
, but not when you have extended one of these types.
当模式类型是 XML 模式类型中的一种,即xsd:date
或 时xsd:dateTime
,JAXB 将为您执行此操作,但当您扩展了这些类型之一时,则不会。
XML Schema (schema.xsd)
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>
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;
}
回答by Evgeniy Dorofeev
If the date is '2001-05-11T00:00:00.000+02:00' use
如果日期是 '2001-05-11T00:00:00.000+02:00' 使用
<xsd:restriction base="xsd:dateTime" />