java原生代码验证xml是否存在语法错误

不依赖第三方工具

核心代码

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;

public class XmlValidateUtils {
	
	private static final DocumentBuilderFactory FACTORY = DocumentBuilderFactory.newInstance();
	
	/**
	 * 验证xml文档是否存在语法错误
	 * @param xmlInputStream
	 * @return true 通过校验, false xml有语法错误或未通过校验
	 * @throws ParserConfigurationException 严重的配置错误
	 */
	public static boolean isValid(InputStream xmlInputStream) throws ParserConfigurationException {
	    return isValid(xmlInputStream, (ErrorHandler) null);
	}
	
	/**
	 * 验证xml文档是否存在语法错误
	 * @param xml
	 * @return true 通过校验, false xml有语法错误或未通过校验
	 * @throws ParserConfigurationException 严重的配置错误
	 * @throws IOException 字符串转输入流错误
	 */
	public static boolean isValid(String xml) throws ParserConfigurationException, IOException {
	    return isValid(xml, (ErrorHandler) null);
	}
	
	/**
	 * 验证xml文档是否存在语法错误
	 * @param xmlInputStream
	 * @param errorHandler xml文档warning、error、fatalError的回调接口
	 * @return true 由errorHandler的方法实现决定,false xml校验未通过
	 * @throws ParserConfigurationException 严重的配置错误
	 */
	public static boolean isValid(InputStream xmlInputStream, ErrorHandler errorHandler) throws ParserConfigurationException {
		DocumentBuilder builder = FACTORY.newDocumentBuilder();
		if (errorHandler != null) {
			builder.setErrorHandler(errorHandler);
		}
		try {
			builder.parse(xmlInputStream);
			return true;
		} catch (Exception e) {
			return false;
		}
	}
	
	/**
	 * 验证xml文档是否存在语法错误
	 * @param xml
	 * @param errorHandler xml文档warning、error、fatalError的回调接口
	 * @return true 由errorHandler的方法实现决定,false xml校验未通过
	 * @throws ParserConfigurationException 严重的配置错误
	 * @throws IOException 字符串转输入流错误
	 */
	public static boolean isValid(String xml, ErrorHandler errorHandler) throws ParserConfigurationException, IOException {
		try (
				ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xml.getBytes());
				) {
			return isValid(xmlInputStream, errorHandler);
		}
	}
}

说明

  1. 如果传入自定义的 errorHandler 参数,则使用自定义的 ErrorHandler。
    如:自定义的 XmlErrorHandler 类,当xml严重错误时执行 fatalError 方法,当xml内容不符合xsd规则时执行 error 方法,此时未抛出异常,而是将异常对象 SAXParseException 加入到对应的 List,由上面的 private static boolean isValid(InputStream xmlInputStream) throws ParserConfigurationException 方法捕获,返回false表示xml存在语法错误;当不存在语法错误时,不执行 error 方法和 fatalError 方法,不抛出 SAXParseException 异常,返回true。
package com.sun.org.apache.xerces.internal.jaxp.validation;

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * {@link ErrorHandler} that throws all errors and fatal errors.
 *
 * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
 */
final class DraconianErrorHandler implements ErrorHandler {

    /**
     * Singleton instance.
     */
    private static final DraconianErrorHandler ERROR_HANDLER_INSTANCE
        = new DraconianErrorHandler();

    private DraconianErrorHandler() {}

    /** Returns the one and only instance of this error handler. */
    public static DraconianErrorHandler getInstance() {
        return ERROR_HANDLER_INSTANCE;
    }

    /** Warning: Ignore. */
    public void warning(SAXParseException e) throws SAXException {
        // noop
    }

    /** Error: Throws back SAXParseException. */
    public void error(SAXParseException e) throws SAXException {
        throw e;
    }

    /** Fatal Error: Throws back SAXParseException. */
    public void fatalError(SAXParseException e) throws SAXException {
        throw e;
    }

}
  1. 如果传入自定义的 errorHandler 参数,则使用自定义的 ErrorHandler。
    如:自定义的 XmlErrorHandler 类,当xml严重错误时执行 fatalError 方法,当xml内容不符合xsd规则时执行 error 方法,此时未抛出异常,而是将异常对象 SAXParseException 加入到对应的 List,上面的 private static boolean isValid(InputStream xmlInputStream) throws ParserConfigurationException 方法不能捕获 SAXParseException 异常,返回true;当捕获到 SAXParseException 异常时,表示xml存在语法错误,返回false。
import java.util.ArrayList;
import java.util.List;

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;

public class XmlErrorHandler implements ErrorHandler {

	private List<SAXParseException> warningExceptions;
	
	private List<SAXParseException> errorExceptions;
	
	private List<SAXParseException> fatalErrorExceptions;

    public XmlErrorHandler() {
        this.warningExceptions = new ArrayList<>();
        this.errorExceptions = new ArrayList<>();
        this.fatalErrorExceptions = new ArrayList<>();
    }

    public List<SAXParseException> getWarningExceptions() {
		return warningExceptions;
	}

	public List<SAXParseException> getErrorExceptions() {
		return errorExceptions;
	}

	public List<SAXParseException> getFatalErrorExceptions() {
		return fatalErrorExceptions;
	}

	@Override
    public void warning(SAXParseException exception) {
		warningExceptions.add(exception);
    }

    @Override
    public void error(SAXParseException exception) {
    	errorExceptions.add(exception);
    }

    @Override
    public void fatalError(SAXParseException exception) {
    	fatalErrorExceptions.add(exception);
    }

}

使用JDK默认的 errorHandler

public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
	String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n"
			+ "<individual>\r\n"
			+ "    <name>student</name>\r\n"
			+ "    <address>\r\n"
			+ "        <zip>00001</zip>\r\n"
			+ "        <city>New <York</city>\r\n"
			+ "    </address>\r\n"
			+ "</individual>";
	
	boolean valid1 = isValid(xml);
	System.out.println(valid1);
}

使用自定义的 errorHandler

/**
 * 验证xml文档是否存在语法错误
 * @param xml
 * @throws RuntimeException 校验程序出错
 * @throws IllegalArgumentException 校验未通过
 */
public static void validate(String xml) {
	XmlErrorHandler errorHandler = new XmlErrorHandler();
	try {
		boolean valid = isValid(xml, errorHandler);
		if (!valid) {
			if (!errorHandler.getFatalErrorExceptions().isEmpty()) {
				throw new IllegalArgumentException("xml:" + xml + "语法错误", errorHandler.getFatalErrorExceptions().get(0));
			}
			throw new RuntimeException("校验程序出错");
		}
	} catch (IllegalArgumentException e) {
		throw e;
	} catch (Exception e) {
		throw new RuntimeException("校验程序出错", e);
	}
	if (!errorHandler.getErrorExceptions().isEmpty()) {
		throw new IllegalArgumentException("xml:" + xml + "校验未通过", errorHandler.getErrorExceptions().get(0));
	}
}

public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
	String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n"
			+ "<individual>\r\n"
			+ "    <name>student</name>\r\n"
			+ "    <address>\r\n"
			+ "        <zip>00001</zip>\r\n"
			+ "        <city>New <York</city>\r\n"
			+ "    </address>\r\n"
			+ "</individual>";
	
	validate(xml);
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值