I try to validate an xml using xsd. So far, everything works fine:
File xsdFile = null;
Source source = new StreamSource(new StringReader(xmlString));
try {
xsdFile = new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD).getFile();
} catch (IOException e) {
throw new FacturxException(e.getMessage());
}
try {
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(xsdFile);
Validator validator = schema.newValidator();
validator.validate(source);
return true;
} catch (SAXException | IOException e) {
throw new FacturxException(e.getLocalizedMessage());
}
My issue is the following: If i compile it in a jar and call the method using the validator, i have errors. As a matter of fact it seems that i can't get the related xsd files.
I tried to solve this issue this way:
Source[] sources = sources = new Source[] {
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_QUALIFIED_DATA)
.getInputStream()),
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_REUSABLE)
.getInputStream()),
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_UNQUALIFIED_DATA)
.getInputStream()),
new StreamSource(
new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD).getInputStream())
Apparently I do have access to those xsd files but it returns src-resolve: Cannot resolve the name 'udt:IDType' to a(n) 'type definition' component
. If i change xsd files order, errors differs...
I'm stuck for the whole day on this.
Based on Michael Kay observation, I implpemented a method to set the SystemId:
private static Source[] buildSources(String pattern) throws SAXException, IOException {
List<Source> sources = new ArrayList<>();
PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = patternResolver.getResources(pattern);
for (Resource resource : resources) {
StreamSource dtd = new StreamSource(resource.getInputStream());
dtd.setSystemId(resource.getURI().toString());
sources.add(dtd);
}
return sources.toArray(new Source[sources.size()]);
}
Pattern looks like this:
"classpath:xsd/BASIC-WL_XSD/**/*.xsd"
xsd files are stored in resources folder ...