Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jaxb - how to map xsd files to URL to find them

Tags:

jaxb

xjc

I have an xsd which has the typical import statements to import other xsd files but unfortunately, the references are hardcoded paths. Is there a way in JAXB to override the location of those imports using a xbj file?

All of these xsds are delivered via another jar(inside the jar) so I would like to get the one off the classpath and when it imports the others try to configure it so it gets the others off the classpath.

thanks, Dean

like image 839
Dean Hiller Avatar asked Dec 21 '22 00:12

Dean Hiller


2 Answers

There's a number of techniques you can use to address the issue:

Catalogs

You can use a catalog file to override schema location. Here's a couple of examples:

Use another schema depending on the namespace:

PUBLIC "http://example.org/A" "others/schema_a.xsd"

Use another schema depending on the schema location:

REWRITE_SYSTEM "https://example.org/a.xsd" "others/schema_a.xsd"

Allows you to use a local copy of a schema file.

See this and this guides. Unfortunatelly, catalog support in XJC is not always working as expected and it's a bit hard to debug it.

Resolving schemas from Maven artifacts

If you're using Maven, you can use maven-jaxb2-plugin which can resolve schemas within Maven artifacts:

REWRITE_SYSTEM "https://example.org/a.xsd" "maven:org.example:a!/a.xsd"

In combination with catalogs, you can make JAXB use a.xsd inside a-XXX.jar instead of https://example.org/a.xsd.

See these sample projects:

  • https://svn.java.net/svn/maven-jaxb2-plugin~svn/trunk/tests/catalog/
  • https://svn.java.net/svn/maven-jaxb2-plugin~svn/trunk/tests/episodes/d/
like image 184
lexicore Avatar answered Mar 12 '23 09:03

lexicore


You could try interacting with XJC programmatically (see below) and plug-in your own EntityResolver to resolve the XML schemas:

import com.sun.codemodel.*;
import com.sun.tools.xjc.*;
import com.sun.tools.xjc.api.*;

SchemaCompiler sc = XJC.createSchemaCompiler();
sc.setEntityResolver(new YourEntityResolver());
sc.setErrorListener(new YourErrorListener());
sc.parseSchema(SYSTEM_ID, element);
S2JJAXBModel model = sc.bind();

Below is a link to a related answer I gave that some people have found useful:

  • https://stackoverflow.com/a/3489799/383861
like image 43
bdoughan Avatar answered Mar 12 '23 10:03

bdoughan