- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
I experienced that Jaxb2Marshaller failed to validate my invalid XML against the XSD while doing the unmarshalling. I'm using Spring 4.0.0.RELEASE and Java 7.
Here is an example:
The XSD file: fruit.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:attribute name="quantity" type="xs:string" />
<xs:element name="fruit">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element ref="banana" />
<xs:element ref="apple" />
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="banana">
<xs:complexType>
<xs:attribute ref="quantity" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="apple">
<xs:complexType>
<xs:attribute ref="quantity" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
I generated the JAXB POJOs from this XSD with Spring Tool Suite to com.testraptor.xml.jaxb
package.
My invalid XML file: invalid.xml
<?xml version="1.0" encoding="UTF-8"?>
<fruit>
<banana quantity="5" />
<apple quantity="3" />
</fruit>
As you can see I broke the schema because there is a choice in the fruit tag and I used banana and apple at the same time.
My Spring configuration file: app-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/oxm
http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd">
<oxm:jaxb2-marshaller id="marshaller" context-path="com.fruit.xml.jaxb" />
</beans>
The main class to test: Main.java
package com.fruit.test;
import java.io.IOException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.xml.sax.SAXException;
import com.fruit.xml.jaxb.Fruit;
public class Main {
public static void main(String[] args) {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"app-context.xml");
//--------------------------------SCHEMA VALIDATION IS OMITTED
Jaxb2Marshaller jaxb2Unmarshaller = (Jaxb2Marshaller) appContext
.getBean("marshaller");
Resource schemaResource = appContext
.getResource("classpath:fruit.xsd");
jaxb2Unmarshaller.setSchema(schemaResource);
Resource xml = appContext.getResource("classpath:invalid.xml");
try {
Fruit fruit = (Fruit) jaxb2Unmarshaller.unmarshal(new StreamSource(xml.getInputStream()));
System.out.println("SCHEMA VALIDATION IS OMITTED:");
System.out.println("Apple quantity is " + fruit.getApple().getQuantity());
System.out.println("Banana quantity is " + fruit.getBanana().getQuantity());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//--------------------------------SCHEMA VALIDATION IS PASSED
SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema;
try {
schema = sf.newSchema(schemaResource.getURL());
JAXBContext context = JAXBContext.newInstance(Fruit.class);
Unmarshaller unmarshaller = (Unmarshaller) context.createUnmarshaller();
unmarshaller.setSchema(schema);
Fruit fruit2 = (Fruit) unmarshaller.unmarshal(xml.getInputStream());
System.out.println("SCHEMA VALIDATION IS PASSED:");
System.out.println("Apple quantity is " + fruit2.getApple().getQuantity());
System.out.println("Banana quantity is " + fruit2.getBanana().getQuantity());
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
When I run the code I get the following result:
INFO: Loading XML bean definitions from class path resource [app-context.xml]
dec. 26, 2013 9:33:22 DE org.springframework.oxm.jaxb.Jaxb2Marshaller createJaxbContextFromContextPath
INFO: Creating JAXBContext with context path [com.fruit.xml.jaxb]
SCHEMA VALIDATION IS OMITTED:
Apple quantity is 3
Banana quantity is 5
javax.xml.bind.UnmarshalException
- with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 4; columnNumber: 24; cvc-complex-type.2.4.d: Invalid content was found starting with element 'apple'. No child element is expected at this point.]
at ...
As you can see the Jaxb2Marshaller forgot to validate my invalid XML file while the Unmarshaller could validate it.
Can anyone give me a clue what could be wrong with my code?
最佳答案
我在运行时配置 Jaxb2Marshaller
时遇到了同样的问题。通过 Spring XML 设置模式的建议解决方案让我开始思考:我的代码设置属性和 Spring 之间有什么区别?
答案很简单:Jaxb2Marshaller
实现 org.springframework.beans.factory.InitializingBean
定义了生命周期方法 afterPropertiesSet()
和这个方法在设置属性后由 Springs BeanFactory
调用。
因此解决方案是在使用 setSchema()
设置架构属性后调用 afterPropertiesSet()
。因为在该方法中,模式属性(它是一个 org.springframework.core.io.Resource
数组)实际上用于设置类型为 javax.xml.validation.Schema 的内部模式字段
稍后用于模式验证。
示例:
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
Resource schema = new ClassPathResource("fruit.xsd");
marshaller.setSchema(schema);
marshaller.setContextPath("com.fruit.xml.jaxb");
// manually call Spring lifecycle method which actually loads the schema resource
marshaller.afterPropertiesSet();
// use marshaller...
关于java - Jaxb2Marshaller 模式验证似乎不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20782120/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!