由于这个问题听起来很简单,我已经寻找解决方案很久了,现在来请求帮助。
我有一个 XML Schema,我使用 xjc 将其用于创建我的 JAXB 绑定。当 XML 是格式正确时,这个过程可以正常工作。但是,如果 XML 不是格式正确的,它也不会报错。当我尝试将 XML 文件反序列化时,我无法想出如何根据模式进行全面的验证。
我成功地使用 ValidationEventCollector 来处理事件。这对于 XML 解析错误(例如标签不匹配)有效,但是当存在必需但完全缺失的标签时,它不会引发任何事件。
据我所见,可以根据模式进行验证,但必须知道路径才能将其传递给 setSchema () 方法。 我遇到的问题是,模式的路径存储在 XML 标头中,而我无法在运行时确定模式将位于何处。 这就是为什么它存储在 XML 文件中的原因:
<?xml version="1.0" encoding="utf-8"?>
<DDSSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/a/big/long/path/to/a/schema/file/DDSSettings.xsd">
<Field1>1</Field1>
<Field2>-1</Field2>
我看到的每个示例都使用setValidating(true),但它现在已经被弃用,所以会抛出异常。
这是我目前的Java代码,似乎只进行XML验证,而不是模式验证:
try {
JAXBContext jc = new JAXBContext() {
private final JAXBContext jaxbContext = JAXBContext.newInstance("blah");
@Override
public Unmarshaller createUnmarshaller() throws JAXBException {
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
ValidationEventCollector vec = new ValidationEventCollector() {
@Override
public boolean handleEvent(ValidationEvent event) throws RuntimeException {
ValidationEventLocator vel = event.getLocator();
if (event.getSeverity() == event.ERROR || event.getSeverity() == event.FATAL_ERROR) {
String error = "XML Validation Exception: " + event.getMessage() + " at row: " + vel.getLineNumber() + " column: " + vel.getColumnNumber();
System.out.println(error);
}
m_unmarshallingOk = false;
return false;
}
};
unmarshaller.setEventHandler(vec);
return unmarshaller;
}
@Override
public Marshaller createMarshaller() throws JAXBException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
@SuppressWarnings("deprecation")
public Validator createValidator() throws JAXBException {
throw new UnsupportedOperationException("Not supported yet.");
}
};
Unmarshaller unmarshaller = jc.createUnmarshaller();
m_ddsSettings = (com.ultra.DDSSettings)unmarshaller.unmarshal(new File(xmlfileName));
} catch (UnmarshalException ex) {
Logger.getLogger(UniversalDomainParticipant.class.getName()).log(
Level.SEVERE,
null, ex);
} catch (JAXBException ex) {
Logger.getLogger(UniversalDomainParticipant.class.getName()).log(
Level.SEVERE,
null, ex);
}
那么正确的验证方式是什么?我原本期望JAXB生成的类有一个validate()方法,但我猜这对Java来说太简单了。