Project

Profile

Help

Proper way to resolve classpath XSD imports

Added by Allen Bagwell over 9 years ago

We have Saxon-EE for schema validation. I am currently experimenting with it, but having a problem with xsd import statements.

As a basic test case, I have a main.xsd file in my classpath under the folder /test-schemas using xs:import to grab a.xsd and b.xsd (each with different namespaces) that reside in the same /test-schemas folder.

I have previously gotten the imports to work in JAXP/Xerces using a custom ResourceResolver. However I'm struggling to do this with the pure Saxon-EE API, and I can't find any examples.

The SchemaManager doesn't seem to natively understand classpaths, so I have been trying to use the SchemaURIResolver to no avail.

Here is my code:

@Test
public void saxonValidationTest() {

   try {
      Processor proc = new Processor(true);
      proc.setConfigurationProperty( "http://saxon.sf.net/feature/validation-warnings", "true");
			
      SchemaManager schemaManager = proc.getSchemaManager();
      SchemaURIResolver resolver = new StandardSchemaResolver(new EnterpriseConfiguration());
      URI baseUri = new URI("classpath:///test-schemas");
      resolver.resolve("urn:testing:message:typea, urn:testing:message:typeb", baseUri.toString(), new String[]{"./"});
      schemaManager.setSchemaURIResolver(resolver);

      InputStream is = this.getClass().getResourceAsStream( "/test-schemas/main.xsd");
      schemaManager.load(new StreamSource(is));

      ...			
   } catch (Exception e) {
      fail(e.getMessage());
   }
}

This is the output I get from the failing exception message:

Warning: at xs:import on line 6 column 76 
  Imported schema document a.xsd cannot be located: java.io.FileNotFoundException
  (/home/afbagwe/workspaces/osgi/framework/libs/core/a.xsd (No such file or directory))
Warning: at xs:import on line 7 column 76 
  Imported schema document b.xsd cannot be located: java.io.FileNotFoundException
  (/home/afbagwe/workspaces/osgi/framework/libs/core/b.xsd (No such file or directory))
Error on line 12 
  The element {kml} is referenced, but has not been declared
Error on line 13 
  The element {message} is referenced, but has not been declared

So to be clear, the code can file my main.xsd file just fine. However the returned sources, instead of searching the classpath, seem to be finding instead the absolute path on my file system but only to the top level of the Maven project I have set up.

Curiously if I modify my code to use a FileReader, it still can't find the import xsd files in the same directory. And assigning a baseURI of "src/test/resources/test-schemas/" still results in precisely the same error message above that I got trying to do a classpath.

Any help is greatly appreciated.

Thanks, Allen


Replies (2)

RE: Proper way to resolve classpath XSD imports - Added by Michael Kay over 9 years ago

We have added support for the Spring-defined classpath:// URI scheme in Saxon 9.7, but it is not supported in 9.6. Support can easily be enabled by a few lines of code in a user-written URIResolver.

If you have an existing LSResourceResolver that does what you need, you could try making it into a Saxon SchemaURIResolver by wrapping it in an instance of com.saxonica.ee.schema.sdoc.LSSchemaResolver.

Note that your call to new EnterpriseConfiguration() is incorrect. You should use the Configuration that already exists to underpin the s9api Processor object, using processor.getUnderlyingConfiguration().

When your main schema document is loaded using a StreamSource that wraps an InputSource or Reader with no known system ID, the base URI of the main schema document will be unknown, which makes it impossible to resolve a relative URI against that base.

RE: Proper way to resolve classpath XSD imports - Added by Allen Bagwell over 9 years ago

Thanks for the heads up about the Configuration.

I wrapped my customer LSResourceResolver with the SchemaURIResolver and it worked!

    (1-2/2)

    Please register to reply