You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java使用JDK1.8 javax.xml.validation API校验XML时如何捕获全部XSD校验错误

问题解决:XML与XSD校验遇到第一个错误就终止,无法收集所有违规错误

核心原因

JDK1.8内置的Xerces XML解析器默认开启「遇到致命校验错误立即终止」的特性,即便自定义ErrorHandler没有抛出任何异常,内置的快速失败逻辑仍会中断校验流程,无法收集后续所有违规错误。

修复方案

步骤1:给Validator添加继续校验的特性

在初始化Validator后,添加如下配置,开启致命错误后继续校验的能力:

// 开启校验遇到错误后继续执行的特性
validator.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);

步骤2:确认ErrorHandler回调逻辑符合要求

你当前的XMLSchemaValidationErrorHandler已经符合要求,三个回调方法(warning/error/fatalError)仅收集异常不抛出SAXException,可保证校验流程不被主动中断。另外你代码中构造方法传入的Validator没有被实际使用,可以按需删除冗余参数。

步骤3:校验完成后统一获取所有错误

校验执行完成后,直接调用errorHandler.getExceptions()即可拿到所有校验违规的异常列表,无需依赖validate方法的抛出异常判断结果。

注意:如果XML本身存在格式致命错误(比如标签未闭合、语法完全不符合XML规范),解析器仍可能提前终止,该场景下无法收集到后续所有错误,仅针对XSD规则校验类的错误可实现全量收集。

完整修改后的代码示例

主校验逻辑

import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collections;
import java.util.List;
import org.xml.sax.SAXParseException;

// 业务校验逻辑
String xsd = ""; // 替换为你的XSD内容
String xml = ""; // 替换为你的XML内容
List<SAXParseException> allErrors = Collections.emptyList();
try {
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = schemaFactory.newSchema(new StreamSource(new StringReader(xsd)));
    Validator validator = schema.newValidator();
    // 关键配置:开启错误后继续校验
    validator.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
    XMLSchemaValidationErrorHandler errorHandler = new XMLSchemaValidationErrorHandler();
    validator.setErrorHandler(errorHandler);
    StringWriter writer = new StringWriter();
    StreamResult result = new StreamResult(writer);
    validator.validate(new StreamSource(new StringReader(xml)), result);
    // 获取所有校验错误
    allErrors = errorHandler.getExceptions();
} catch (SAXException e) {
    // 捕获解析层面的异常,不影响已收集的错误
} catch (IllegalArgumentException i) {
    // 参数异常处理
} catch (IOException err) {
    // IO异常处理
} catch (Exception e) {
    // 其他异常处理
}

简化后的错误处理器

package com.xml.validation.utils;

import java.util.LinkedList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class XMLSchemaValidationErrorHandler implements ErrorHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(XMLSchemaValidationErrorHandler.class);
    private final List<SAXParseException> exceptions = new LinkedList<>();

    @Override
    public void warning(SAXParseException exception) throws SAXException {
        LOGGER.error("warning SAXParseException :::{}", exception.getMessage());
        exceptions.add(exception);
    }

    @Override
    public void error(SAXParseException exception) throws SAXException {
        LOGGER.error("error SAXParseException Message ::: {}", exception.getMessage());
        exceptions.add(exception);
    }

    @Override
    public void fatalError(SAXParseException exception) throws SAXException {
        LOGGER.error("fatalError SAXParseException ::: {}", exception.getMessage());
        exceptions.add(exception);
    }

    public List<SAXParseException> getExceptions() {
        return exceptions;
    }
}

内容的提问来源于stack exchange,提问作者Rajashekhar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 11:36:04