使用XercesJ验证含外部引用的XSD 1.1时抛出SAXParseException
解决XercesJ 2.12.2验证XSD 1.1时无法加载外部Schema的问题
问题根源
你当前的代码使用StreamSource加载主XSD时,没有指定基础URI(systemId),导致XML解析器无法根据相对路径定位到被xs:include引用的外部XSD文件,进而无法解析其中定义的类型。
解决方案
1. 为主XSD的StreamSource设置systemId
解析器需要通过systemId确定主XSD的位置,才能正确解析相对路径的外部引用。根据你的XSD存放位置,选择对应方式设置:
情况1:XSD在classpath(如resources目录)
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1"); // 启用XSD 1.1特性(确保XercesJ支持) factory.setFeature("http://apache.org/xml/features/validation/schema-version-1.1", true); factory.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true); // 获取主XSD的URL作为systemId URL schemaUrl = getClass().getClassLoader().getResource("Example.xsd"); StreamSource mainSchemaSource = new StreamSource(loadExampleSchema("Example.xsd")); // 设置systemId,让解析器能定位外部XSD mainSchemaSource.setSystemId(schemaUrl.toString()); Schema schema = factory.newSchema(mainSchemaSource); Validator validator = schema.newValidator(); validator.validate(new StreamSource(new ByteArrayInputStream(xml.getBytes())));
情况2:XSD在本地文件系统
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1"); // 启用XSD 1.1特性 factory.setFeature("http://apache.org/xml/features/validation/schema-version-1.1", true); factory.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true); File mainSchemaFile = new File("/path/to/your/Example.xsd"); StreamSource mainSchemaSource = new StreamSource(new FileInputStream(mainSchemaFile)); // 设置文件URI作为systemId mainSchemaSource.setSystemId(mainSchemaFile.toURI().toString()); Schema schema = factory.newSchema(mainSchemaSource); Validator validator = schema.newValidator(); validator.validate(new StreamSource(new ByteArrayInputStream(xml.getBytes())));
2. 检查外部XSD的路径正确性
确保NIEM_1.xsd、NIEM_2.xsd与主XSDExample.xsd处于同一目录,或者schemaLocation属性填写了正确的相对路径(如./subdir/NIEM_1.xsd)。同时移除代码中重复的xs:include(当前重复引用了NIEM_2.xsd,虽不报错但冗余)。
3. 验证依赖兼容性
- 确认
xercesImpl.jar是2.12.2版本(该版本原生支持XSD 1.1) - 确保
xml-apis.jar与xercesImpl.jar版本匹配,避免API冲突
额外排查点
如果仍报错,可开启XercesJ的调试日志,查看解析器加载外部XSD的具体路径,定位是否存在路径错误:
factory.setErrorHandler(new ErrorHandler() { @Override public void warning(SAXParseException exception) throws SAXException { System.out.println("Warning: " + exception.getMessage()); } @Override public void error(SAXParseException exception) throws SAXException { System.out.println("Error: " + exception.getMessage()); } @Override public void fatalError(SAXParseException exception) throws SAXException { System.out.println("Fatal Error: " + exception.getMessage()); } });
内容的提问来源于stack exchange,提问作者user1852
相关产品推荐
相关产品推荐

