加载含include和import的XSD验证架构无法解析类型引用问题咨询
根因分析
Java 默认的 SchemaFactory 处理**相同命名空间的多次xs:import**时,仅会加载第一个匹配的XSD文件,后续同命名空间的import会被直接丢弃。你的最小示例中第一个import的siri_modes-v1.1.xsd是空的,包含目标类型的siri_operator_support-v2.0.xsd被跳过,所以找不到类型定义。
解决方案
方案1:手动传入所有依赖XSD构造Schema
不需要修改原XSD,把所有用到的XSD资源(所有SIRI命名空间的XSD + OJP主XSD)按顺序组装为数组传入newSchema方法,处理器会自动合并所有同命名空间的定义:
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // 按顺序加载所有SIRI相关XSD,再加载OJP主XSD Source[] schemas = new Source[] { new StreamSource(new URL("https://raw.githubusercontent.com/VDVde/OJP/master/siri_model/siri_modes-v1.1.xsd").openStream()), new StreamSource(new URL("https://raw.githubusercontent.com/VDVde/OJP/master/siri_model/siri_operator_support-v2.0.xsd").openStream()), // 其他所有SIRI命名空间的XSD都提前加在这里 new StreamSource(new URL("https://raw.githubusercontent.com/VDVde/OJP/master/OJP_Requests.xsd").openStream()) }; Schema schema = factory.newSchema(schemas); schema.newValidator().validate(...);
注:如果有本地缓存的XSD文件,优先读本地,避免网络请求不稳定。
方案2:自定义资源解析器拦截import请求
如果依赖的XSD数量太多不好手动枚举,可以实现LSResourceResolver,拦截所有http://www.siri.org.uk/siri命名空间的解析请求,统一返回全量的SIRI类型定义:
public class SiriResourceResolver implements LSResourceResolver { @Override public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { // 只要是SIRI命名空间的请求,返回合并后的SIRI全量XSD输入流 if ("http://www.siri.org.uk/siri".equals(namespaceURI)) { LSInput input = new DOMInputImpl(); // 这里传入你本地/远程的合并后SIRI全量XSD流 input.setByteStream(ClassLoader.getSystemResourceAsStream("siri_all.xsd")); return input; } // 其他命名空间走默认解析逻辑 return null; } } // 使用方式 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); factory.setResourceResolver(new SiriResourceResolver()); Schema schema = factory.newSchema(new URL("https://raw.githubusercontent.com/VDVde/OJP/master/OJP_Requests.xsd"));
方案3:本地预合并SIRI命名空间的所有XSD
把所有targetNamespace="http://www.siri.org.uk/siri"的XSD内容合并为单个siri_all.xsd,本地缓存后直接使用,彻底避免同命名空间多次import的兼容问题。
内容的提问来源于stack exchange,提问作者Itchy
相关产品推荐
相关产品推荐

