Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>After much searching, I finally found the answer. Hopefully this will help someone else. There are already other threads on StackOverflow relating to this issue, but without knowing the proper keywords, I wasn't finding the responses.</p> <p>The solution is to use an LSResourceResolver for the schema factory. ie:</p> <pre><code>schemaFactory.setResourceResolver(new LSResourceResolver(){}) </code></pre> <p>where LSResourceResolver() is responsible for returning the include/import resource that is required by the XSD.</p> <p>Searching for LSResourceResolver in SO found a few useful threads: <a href="https://stackoverflow.com/a/3830649/827480">https://stackoverflow.com/a/3830649/827480</a>, <a href="https://stackoverflow.com/a/2342859/827480">https://stackoverflow.com/a/2342859/827480</a></p> <p>I will try to post my own solution later when I have a little more time, but it closely follows what was already suggested in the two above links (mine is a little more simplified by using Strings instead of streams...).</p> <p><strong>EDIT</strong></p> <p>As promised, here is the snippet of code I ended up with:</p> <pre><code> // get the schemas used by this class final Map&lt;String, String&gt; schemas = new HashMap&lt;String,String&gt;(); schemas.putAll(generateSchemas(jc)); List&lt;StreamSource&gt; sources = new ArrayList&lt;StreamSource&gt;(); for( String schema : schemas.values() ) sources.add( new StreamSource( new ByteArrayInputStream(schema.getBytes()))); SchemaFactory sf = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI ); sf.setResourceResolver(new LSResourceResolver() { @Override public LSInput resolveResource(String type, final String namespaceURI, String publicId, String systemId, String baseURI){ logger.debug( "Need to resolve Resource: " + namespaceURI ); return new LSInput(){ @Override public String getStringData() { // return the schema if found if( schemas.containsKey(namespaceURI)){ if( logger.isTraceEnabled()) logger.trace("resourceResolver: Resolving schema for namespace: " + namespaceURI + schemas.get(namespaceURI) ); return schemas.get(namespaceURI); } else return null; } @Override public Reader getCharacterStream() { return null; } @Override public void setCharacterStream(Reader paramReader) { } @Override public InputStream getByteStream() { return null; } @Override public void setByteStream(InputStream paramInputStream) { } @Override public void setStringData(String paramString) { } @Override public String getSystemId() { return null; } @Override public void setSystemId(String paramString) { } @Override public String getPublicId() { return null; } @Override public void setPublicId(String paramString) { } @Override public String getBaseURI() { return null; } @Override public void setBaseURI(String paramString) { } @Override public String getEncoding() { return null; } @Override public void setEncoding(String paramString) { } @Override public boolean getCertifiedText() { return false; } @Override public void setCertifiedText(boolean paramBoolean) { } }; } }); // validate the schema u.setSchema(sf.newSchema(sources.toArray(new StreamSource[]{}))); </code></pre> <p>and method generateSchemas(jc):</p> <pre><code>private Map&lt;String, String&gt; generateSchemas (JAXBContext jaxbContext) throws JAXBException{ // generate the schemas final Map&lt;String, ByteArrayOutputStream&gt; schemaStreams = new LinkedHashMap&lt;String,ByteArrayOutputStream&gt;(); try { jaxbContext.generateSchema(new SchemaOutputResolver(){ @Override public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); logger.debug( "GenerateSchemas: adding namespace: " + namespaceUri); schemaStreams.put(namespaceUri, out); StreamResult streamResult = new StreamResult(out); streamResult.setSystemId(""); return streamResult; }}); } catch (IOException e) { // no IO being performed. Can safely ignore any IO exception. } // convert to a list of string Map&lt;String,String&gt; schemas = new LinkedHashMap&lt;String,String&gt;(); for( Map.Entry&lt;String, ByteArrayOutputStream&gt; entry : schemaStreams.entrySet() ){ String schema = entry.getValue().toString(); String namespace = entry.getKey(); schemas.put(namespace, schema); } // done return schemas; } </code></pre> <p><strong>END EDIT</strong></p> <p>I hope this can help someone else in the future.</p> <p>Thanks,</p> <p>Eric</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload