JAR包内通过XSD验证XML遇类型解析错误求助
本地开发时通过ClassPathResource.getFile()加载XSD文件能正常完成XML验证,但打包成JAR后,因JAR内资源并非文件系统的File对象,getFile()调用失败。改用直接读取InputStream的方式虽能获取XSD内容,但XSD间的依赖引用(如udt:IDType这类跨文件类型)因缺少基础URI,导致SchemaFactory无法解析这些关联,最终抛出src-resolve错误。
核心思路是给每个StreamSource指定正确的系统ID(即资源在classpath中的路径),让SchemaFactory能基于此路径找到依赖的XSD文件。
方法1:为StreamSource显式设置系统ID
利用ClassPathResource的资源路径作为系统ID,确保SchemaFactory能定位到关联依赖:
Source[] sources = new Source[] { new StreamSource( new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_QUALIFIED_DATA).getInputStream(), FacturxConstants.FACTUR_X_MINIMUM_XSD_QUALIFIED_DATA), new StreamSource( new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_REUSABLE).getInputStream(), FacturxConstants.FACTUR_X_MINIMUM_XSD_REUSABLE), new StreamSource( new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_UNQUALIFIED_DATA).getInputStream(), FacturxConstants.FACTUR_X_MINIMUM_XSD_UNQUALIFIED_DATA), new StreamSource( new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD).getInputStream(), FacturxConstants.FACTUR_X_MINIMUM_XSD) }; SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = schemaFactory.newSchema(sources); Validator validator = schema.newValidator(); validator.validate(source);
这里StreamSource的第二个参数会作为资源的基础URI,SchemaFactory解析XSD内的引用时,会基于此路径查找依赖文件。
方法2:直接用资源URI创建StreamSource(更简洁)
无需手动处理InputStream,直接通过ClassPathResource的URI构建StreamSource:
List<StreamSource> sourceList = new ArrayList<>(); sourceList.add(new StreamSource( new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_QUALIFIED_DATA).getURI().toString())); sourceList.add(new StreamSource( new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_REUSABLE).getURI().toString())); sourceList.add(new StreamSource( new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD_UNQUALIFIED_DATA).getURI().toString())); sourceList.add(new StreamSource( new ClassPathResource(FacturxConstants.FACTUR_X_MINIMUM_XSD).getURI().toString())); SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = schemaFactory.newSchema(sourceList.toArray(new Source[0])); Validator validator = schema.newValidator(); validator.validate(source);
这种方式让SchemaFactory自行处理资源加载,同时保留了资源的路径上下文,能正确解析跨XSD的引用关系。
失败原因说明
仅传入InputStream时,StreamSource没有关联的基础URI,SchemaFactory无法知晓当前XSD文件的位置,自然无法解析它对其他XSD中类型/元素的引用,这就是调整XSD顺序会出现不同错误的原因——依赖引用的解析顺序被打乱,且始终找不到正确的依赖文件。
- 确认所有XSD文件都正确放置在
src/main/resources(或对应classpath目录)下,打包工具(Maven/Gradle)配置正确,确保资源被完整打包进JAR。 - 检查XSD内部的
import/include语句,其引用路径需与classpath中的资源路径完全匹配。
内容的提问来源于stack exchange,提问作者davidvera

