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