Search code examples
javaxmlxsdxsd-validation

Validating xml through xsd files inside a JAR


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.


Solution

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