JAXB SchemaFactory源命令必须遵循模式之间的导入顺序吗?

使用最新的JAXB(Sun)并具有模式层次结构,这些模式在模式之间使用导入指令来共享类型定义。 在JAXB中对Marshaller / Unmarshaller的setSchema调用中激活了模式validation,这应该将validation推迟到Xerces(使用Java 1.5)。 在使用SchemaFactory创建Schema对象时,我不想知道模式之间的import指令的顺序。 不幸的是,我还没有找到允许这个的Xercesfunction/属性。 例如,如果通过导入将a.xsd拉入b.xsd,则以下代码不起作用:

FileInputStream a = new FileInputStream("a.xsd"); FileInputStream b = new FileInputStream("b.xsd"); Schema schema = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema( new Source[] { new StreamSource(b), new StreamSource(a) } ); 

Source数组的顺序必须是a.xsd然后是b.xsd。 有什么方法吗?

如果在根源上创建架构,然后设置ResourceResolver(LSResourceResolver)以在架构创建期间解析其他导入的架构,该怎么办?

代码的后期。

生成validation架构:

 SchemaFactory factory = SchemaFactory .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); factory.setResourceResolver(new SimpleResolver(streams)); .... Schema schemaGrammers = factory.newSchema(streams.toArray(new SchemaSource[0])); 

Schema(schemaGrammers对象)被注入Marshaller:

 Marshaller m = ...createMarshaller(); m.setSchema(); 

SimpleResolver实现了LSResourceResolver类:

 private class SimpleResolver implements LSResourceResolver { private Set streams; public SimpleResolver(Set streams) { this.streams = streams; } @Override public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { DOMImplementationRegistry registry; try { registry = DOMImplementationRegistry.newInstance(); DOMImplementationLS domImplementationLS = (DOMImplementationLS) registry .getDOMImplementation("LS 3.0"); LSInput ret = domImplementationLS.createLSInput(); for (Source source : streams) { SchemaSource schema = (SchemaSource) source; if (schema.getResourceName().equals( schema.getResourceName(systemId)) & schema.getTargetNamespace().equals(namespaceURI)) { logger.debug( "Resolved systemid [{}] with namespace [{}]", schema.getResourceName(systemId), namespaceURI); URL url = new URL(schema.getSystemId()); URLConnection uc = url.openConnection(); ret.setByteStream(uc.getInputStream()); ret.setSystemId(systemId); return ret; } } } catch (ClassCastException e) { logger.error(e.getMessage()); } catch (ClassNotFoundException e) { logger.error(e.getMessage()); } catch (InstantiationException e) { logger.error(e.getMessage()); } catch (IllegalAccessException e) { logger.error(e.getMessage()); } catch (FileNotFoundException e) { logger.error(e.getMessage()); } catch (IOException e) { logger.error(e.getMessage()); } logger.error("No stream found for system id [{}]", systemId); return null; } } 

必须创建新的输入流否则会发生冲突。 不知道为什么(没有调试代码),但我传递给构造函数的流[即。 已经读取了Set对象]。