'XML validation against XSD with javax.xml.validation.Validator: cannot resolve types come from 2nd XSD

I am trying to write a method that validates XML against XSD. In my case, I have multiple XSD files.

When I use tools like IntelliJ IDEA to generate a sample XML from my main XSD everything looks fine: the sample XML is generated and looks as I expect. So I think that my XSD files are okay.

This is my simplified main XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:ds="http://www.w3.org/2000/09/xmldsig#">

    <xsd:import schemaLocation="xmldsig-core-schema.xsd" namespace="http://www.w3.org/2000/09/xmldsig#" />

    <xsd:element name="Message">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="messageId" type="xsd:string" />
                <xsd:element ref="ds:Signature" minOccurs="0" />
            </xsd:sequence>
            <xsd:attribute name="Id" type="xsd:string" use="optional"/>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

I downloaded and put the xmldsig-core-schema.xsd in the same directory with my XSD files.

The error I get:

org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name 'ds:Signature' to a(n) 'element declaration' component.

Java code:

InputStream xsdStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("schema/my.xsd");
// 1. InputStream xsdSignatureStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("schema/xmldsig-core-schema.xsd");

Source[] sources = new StreamSource[1];
sources[0] = new StreamSource(xsdStream);
// 2. sources[1] = new StreamSource(xsdSignatureStream);

SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
// 3. schemaFactory.setResourceResolver(new ClasspathResourceResolver());
Schema schema = schemaFactory.newSchema(sources);

Validator validator = schema.newValidator();

String xmlString = "...";
StringReader xmlStringReader = new StringReader(xmlString)
Source source = new StreamSource(xmlStringReader);
validator.validate(source);

So it seems that the javax.xml.validation.Validator does not see my 2nd XSD file. So I tried to add it when I initialize the javax.xml.validation.Schema but it does not help (see commented lines 1. and 2.).

I also tried to create and add an external ResourceResolver (see commented line 3.), but it does not help.

Comment: The streams I use are initialized properly, the file paths are good, I can read the content from streams and log it as strings.

What I miss here?



Solution 1:[1]

I suspect that when the schema document is loaded using getResourceAsStream("schema/my.xsd"); it doesn't have a known base URI and therefore the relative URI xmldsig-core-schema.xsd doesn't resolve properly. Try setting a base URI (systemId property) on your StreamSource object.

Solution 2:[2]

I had same error: org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name 'ds:Signature' to a(n) 'element declaration' component.

And wasted several hours trying to handle it somehow. Try to remove from "xmldsig-core-schema.xsd" all content between:

<?xml version="1.0" encoding="utf-8"?>

and

<schema

It's DOCTYPE definition in that place and my assumption, that parser can't handle it correctly.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Michael Kay
Solution 2 Vadim Ponomarev