java - 在 Grails 中创建 XSD 模式 validator 时如何避免调用 w3.org

标签 java xml grails xsd

我使用具有以下代码(已编辑)的服务来根据 XSD 文件验证 XML。 xsd 文件放在 grails-app/conf/xsd 中,以供类加载器找到。

import javax.xml.transform.stream.StreamSource
import javax.xml.validation.SchemaFactory
import javax.xml.validation.Schema
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI

class MyService {

    Schema schema

    MyService() {
        def factory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI),
            myXsd = this.class.classLoader.getResource("xsd/my.xsd")
        schema = factory.newSchema(myXsd)
    }

    void validate(String xml) {
        def validator = schema.newValidator()
        validator.validate(new StreamSource(new StringReader(xml)))
    }
}

它可以工作,但是 XSD 有一些从 w3.org 获取的外部资源。

使用网络捕获工具,我跟踪了以下下载:

http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd
http://www.w3.org/2001/XMLSchema.dtd
http://www.w3.org/2001/datatypes.dtd

如何在每次创建服务时缓存本地副本并避免往返?

我尝试了以下方法:

MyService() {
    def factory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI),
        resolver = new XMLCatalogResolver(),
        catalogs = [this.class.classLoader.getResource("xsd/catalog.xml").file],
        myXsd = this.class.classLoader.getResource("xsd/my.xsd")
    resolver.catalogList = catalogs
    factory.setResourceResolver resolver
    schema = factory.newSchema(myXsd)
}

然后我创建了一个 xsd/catalog.xml 文件:

<?xml version="1.0"?>
<!DOCTYPE catalog PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
          "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public">
    <uri name="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"
         uri="xmldsig-core-schema.xsd"/>
    <uri name="http://www.w3.org/2001/XMLSchema.dtd" uri="XMLSchema.dtd"/>
    <uri name="http://www.w3.org/2001/datatypes.dtd" uri="datatypes.dtd"/>
</catalog>

我在与目录相同的目录中下载了 XSD 和 DTD 的本地副本。但它仍然无法正常工作,启动时间和网络捕获工具证明了这一点。

我做错了什么?有没有更简单的方法?

最佳答案

已解决。

我找到了 this page解释了此类 XML 目录的格式。

对于 XSD,我需要将其 namespace (而非其 URL)放入 <uri name="..." 中标签,而对于 DTD,我必须将其公共(public) ID(PUBLIC 之后的字符串)放入 <public publicId="..." 中标签:

<?xml version="1.0"?>
<!DOCTYPE catalog
    PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
    "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public">
    <uri name="http://www.w3.org/2000/09/xmldsig#" uri="xmldsig-core-schema.xsd"/>
    <public publicId="-//W3C//DTD XMLSchema 200102//EN" uri="XMLSchema.dtd"/>
    <public publicId="datatypes" uri="datatypes.dtd"/>
</catalog>

其他都还好

关于java - 在 Grails 中创建 XSD 模式 validator 时如何避免调用 w3.org,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29148822/

相关文章:

java - Android中如何用Java创建涟漪效果

java - 从 ListView 中删除行的动画

grails - grails install-searchable-config

hibernate - Grails Hibernate session 只读

java - For 循环未在 Java 中运行

java - 注册EventProcessorHost时失败

node.js - 使用nodejs中xmlbuilder包中的内置streamWriter

json - 如何在Grails中更新现有JSON对象的参数?

Java递归1234到4321为例

java - 创建 HTable 时出错