我有一个XML模式,我用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,ex); }
那么进行此验证的正确方法是什么?我期待在JAXB生成的类上有一个validate()方法,但是我猜这对Java来说太简单了.
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); Schema schema = factory.newSchema(); Unmarshaller unmarshaller = jc.createUnmarshaller(); unmarshaller.setSchema(schema); m_ddsSettings = (com.ultra.DDSSettings)unmarshaller.unmarshal(new File(xmlfileName));
耻辱了24小时的最好的部分找到答案!
SchemaFactory.newSchema()
的javadoc说:
For XML Schema,this method creates a
Schema object that performs validation
by using location hints specified in
documents.The returned Schema object assumes that if documents refer to the same URL in the schema location hints,they will always resolve to the same schema document. This asusmption allows implementations to reuse parsed results of schema documents so that multiple validations against the same schema will run faster.
@H_301_39@