Java 在Grails中创建XSD模式验证器时如何避免调用w3.org

Java 在Grails中创建XSD模式验证器时如何避免调用w3.org,java,xml,grails,xsd,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_U

我使用一个带有以下代码(已编辑)的服务来根据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的本地副本下载到与目录相同的目录中。但它仍然不起作用,启动时间和网络捕获工具证明了这一点

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

解决了

我发现这解释了这种XML目录的格式

对于XSD,我需要将其名称空间(而不是URL)放入

<?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>