【问题标题】:Validating against a Schema with JAXB使用 JAXB 对 Schema 进行验证
【发布时间】:2011-01-30 07:34:49
【问题描述】:

我一直在寻找解决这个问题的时间太长了考虑如何方便听起来是那么我来一些帮助。 P>

我有我与XJC用于创建我的JAXB绑定的XML架构。当形成良好的XML这工作得很好。不幸的是,还时不能很好地形成的XML不抱怨。我无法弄清楚如何做正确的全面验证在架构上,当我试图来解读一个XML文件。 P>

我已经成功地使用ValidationEventCollector来处理事件,这适用于XML解析错误,如不匹配的标签,但不会引发任何事件时有所需标签,但是完全不存在。 P>

这是我所看到的验证可以做到againsta模式,但你必须知道的路径,模式,以将其传递到的setSchema()方法。我的问题是,路径架构存储在XML头,我不能在这里的模式将是运行时间knwo。这就是为什么它存储在XML文件中: P>

<?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用途(真),这是现在已经过时,所以抛出异常。 P>

这是Java代码,我到目前为止,这似乎只能做XML验证,而不是架构验证: P>

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太简单。 P>

【问题讨论】:

    标签: xml validation schema jaxb well-formed


    【解决方案1】:

    好的,我找到了解决方案。使用架构工厂创建架构,但不指定架构文件,使其与 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 说:

    对于 XML Schema,此方法创建一个 执行验证的模式对象 通过使用指定的位置提示 文件。

    返回的 Schema 对象假定 如果文件提到相同 架构位置提示中的 URL,它们 将始终解析为相同的架构 文档。这个假设允许 重用已解析的实现 模式文档的结果,以便 针对相同的多个验证 架构将运行得更快。

    【讨论】:

    【解决方案2】:

    据我所知,您只需将带有Marshaller.setSchema() 的架构设置为由SchemaFactory 从您的DDSSettings.xsd 创建的架构。这将打开验证。

    【讨论】:

    • 但问题是我在编译时不知道该 XSD 文件的路径,并且在运行时没有给出它 - 它仅存储在 XML 文件标题中。
    • 但是如果你有 jaxb 类,它们应该是从模式中生成的。为什么不在您的项目中包含架构?
    • JAXB 没有必须使用模式和生成的代码,它在没有模式的情况下也能很好地工作。
    猜你喜欢
    • 2014-03-18
    • 2011-06-19
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-02
    • 2021-09-02
    相关资源
    最近更新 更多