Validate an XML against an XSD in Java / Getting a hold of the schemaLocation

后端 未结 1 1814
旧巷少年郎
旧巷少年郎 2020-12-17 03:11

How can one validate an XML file using an XSD in Java? We don\'t know the schema in advance. I would like to be able to get the schemaLocation, download the XSD

相关标签:
1条回答
  • 2020-12-17 03:37

    Given that you are using Xerces (or JDK default), have you tried setting this feature to true on the factory: http://apache.org/xml/features/validation/schema. There are other features that you can play with regarding schemas: http://xerces.apache.org/xerces2-j/features.html

    UPDATE 2 (for caching):

    Implement a org.w3c.dom.ls.LSResourceResolver and set this on the SchemaFactory using the setResourceResolver method. This resolver would either get the schema from cache or fetch it from wherever the location refers to.

    UPDATE 3:

    LSResourceresolver example (which I think will be a good starting point for you):

    /**
     * Resolves resources from a base URL
     */
    public class URLBasedResourceResolver implements LSResourceResolver {
    
    private static final Logger log = LoggerFactory
            .getLogger(URLBasedResourceResolver.class);
    
    private final URI base;
    
    private final Map<URI, String> nsmap;
    
    public URLBasedResourceResolver(URL base, Map<URI, String> nsmap)
            throws URISyntaxException {
        super();
        this.base = base.toURI();
        this.nsmap = nsmap;
    }
    
    @Override
    public LSInput resolveResource(String type, String namespaceURI,
            String publicId, String systemId, String baseURI) {
        if (log.isDebugEnabled()) {
            String msg = String
                    .format("Resolve: type=%s, ns=%s, publicId=%s, systemId=%s, baseUri=%s.",
                            type, namespaceURI, publicId, systemId, baseURI);
            log.debug(msg);
        }
        if (type.equals(XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
            if (namespaceURI != null) {
                try {
                    URI ns = new URI(namespaceURI);
                    if (nsmap.containsKey(ns))
                        return new MyLSInput(base.resolve(nsmap.get(ns)));
                } catch (URISyntaxException e) {
                    // ok
                }
            }
        }
        return null;
    }
    
    }
    

    The implementation of MyLSInput is really boring:

    class MyLSInput implements LSInput {
    
    private final URI url;
    
    public MyLSInput(URI url) {
        super();
        this.url = url;
    }
    
    @Override
    public Reader getCharacterStream() {
        return null;
    }
    
    @Override
    public void setCharacterStream(Reader characterStream) {
    
    }
    
    @Override
    public InputStream getByteStream() {
        return null;
    }
    
    @Override
    public void setByteStream(InputStream byteStream) {
    
    }
    
    @Override
    public String getStringData() {
        return null;
    }
    
    @Override
    public void setStringData(String stringData) {
    
    }
    
    @Override
    public String getSystemId() {
        return url.toASCIIString();
    }
    
    @Override
    public void setSystemId(String systemId) {
    }
    
    @Override
    public String getPublicId() {
        return null;
    }
    
    @Override
    public void setPublicId(String publicId) {
    }
    
    @Override
    public String getBaseURI() {
        return null;
    }
    
    @Override
    public void setBaseURI(String baseURI) {
    
    }
    
    @Override
    public String getEncoding() {
        return null;
    }
    
    @Override
    public void setEncoding(String encoding) {
    
    }
    
    @Override
    public boolean getCertifiedText() {
        return false;
    }
    
    @Override
    public void setCertifiedText(boolean certifiedText) {
    
    }
    
    }
    
    0 讨论(0)
提交回复
热议问题