xml – 使用JAXB验证模式

前端之家收集整理的这篇文章主要介绍了xml – 使用JAXB验证模式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我一直在寻找这个问题的解决方案太久考虑到这听起来有多容易,所以我来帮忙.

我有一个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来说太简单了.

好的,我找到了解决方案.使用模式工厂来创建模式,但不指定模式文件使其能够与XML文件中指定的noNamespaceSchemaLocation一起使用.

所以从上面的代码已经添加了:

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.

原文链接:https://www.f2er.com/xml/292776.html

猜你在找的XML相关文章