XSD校验XML时日期字段触发SAXNotRecognizedException异常如何解决
异常根因定位
该org.xml.sax.SAXNotRecognizedException异常与你定义的xsd:dateTime类型、XSLT中current-dateTime()的日期生成逻辑无直接关联。
报错核心是当前使用的XML解析器不识别http://javax.xml.XMLConstants/property/accessExternalDTD这个安全属性:该属性是JDK 7u40、JDK 8及以上版本新增的安全控制项,用于限制XML解析过程中访问外部DTD资源,避免XXE注入风险。报错出现在日期字段节点,只是因为XML解析顺序刚好走到该位置时触发了DTD访问校验逻辑。
排查步骤
- 确认运行环境的JDK版本:如果是JDK 7u40以下、JDK 6及更早版本,原生不支持该属性,会直接抛出不识别异常
- 检查项目依赖的XML解析器:如果项目引入了独立的Xerces解析器包,版本低于2.12.0的话也不支持该安全属性
- 核对XML校验的代码逻辑:确认是否在
SAXParserFactory/SchemaFactory上硬编码强制设置了该属性,解析器不支持的情况下强制设置就会触发该异常
解决方案
场景1:JDK版本过低/依赖老旧Xerces包
- 支持升级依赖的场景:升级JDK到8u101及以上版本,若引入了独立Xerces包则升级到
xercesImpl:2.12.2及以上版本即可原生支持该属性 - 无法升级依赖的场景:移除代码中手动设置
accessExternalDTD属性的逻辑,测试环境可临时添加JVM启动参数-Djavax.xml.accessExternalDTD=all跳过限制,生产环境建议替换为对应旧版本解析器支持的安全控制规则
场景2:属性设置对象错误
accessExternalDTD属性在校验XSD时需要设置给SchemaFactory而非SAXParserFactory,且建议先判断解析器是否支持该属性再赋值,正确的代码示例如下:
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); String accessExternalDTD = "http://javax.xml.XMLConstants/property/accessExternalDTD"; // 先判断属性是否被支持,避免抛出不识别异常 if (factory.isPropertySupported(accessExternalDTD)) { // 生产环境建议根据实际需求配置允许的DTD来源,不要设置为all factory.setProperty(accessExternalDTD, "all"); } Schema schema = factory.newSchema(new File("你的XSD文件路径")); Validator validator = schema.newValidator(); validator.validate(xmlSource);
日期字段额外校验提示
待上述属性异常解决后,你可额外确认XSLT生成的日期格式是否符合xsd:dateTime的标准要求:标准格式为yyyy-MM-dd'T'HH:mm:ss.SSSXXX,例如2024-05-20T14:30:00.000+08:00,如果格式不匹配会单独抛出类型不匹配的校验错误。
内容的提问来源于stack exchange,提问作者ShwetaB
相关产品推荐
相关产品推荐

