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