最近项目须要使用xsd对xml进行预校验,因而封装了一个工具类,来完成校验工做。 完整代码以下:java
import java.io.File; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.List; import java.util.Locale; import javax.xml.XMLConstants; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; public class MultiSchemaValidator { // private static final Logger logger = LoggerFactory.getLogger(MultiSchemaValidator.class); static{ System.setProperty("jdk.xml.maxOccurLimit", "9999"); //默认的maxOccur为5000,而咱们项目中要求9999 Locale.setDefault(Locale.CHINA); //若是项目不考虑国际化的话 } public static List<SAXParseException> validateXMLSchema(String xsdPath, String xml){ final List<SAXParseException> errors = new ArrayList<>(); try { SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); String path = Thread.currentThread().getContextClassLoader().getResource("").getPath(); Schema schema = factory.newSchema(new File(path + xsdPath)); Validator validator = schema.newValidator(); validator.setErrorHandler(new ErrorHandler() { @Override public void warning(SAXParseException exception) throws SAXException { // logger.debug("warning ex", exception); } @Override public void fatalError(SAXParseException exception) throws SAXException { // logger.debug("fatalError ex", exception); } @Override public void error(SAXParseException exception) throws SAXException { // logger.debug("error ex", exception); errors.add(exception); } }); validator.validate(new StreamSource(new StringReader(xml))); } catch (IOException | SAXException e) { System.out.println("Exception: "+e.getMessage()); } return errors; } //测试代码 public static void main(String[] args) throws Exception { String schemaURI = "xsd/Manifest.xsd"; String xml = ""; List<SAXParseException> errors = validateXMLSchema(schemaURI, xml); for(SAXParseException ex : errors){ System.out.println(ex.getLineNumber() + "行," + ex.getColumnNumber() + "列," + ex.getMessage()); } } }
该代码应该能够完成通常需求。不过须要注意如下问题:apache
- xsd中使用
<xs:import>
<xs:include>
引入其余xsd文件时,不要将xsd打包到jar中,这种方式不支持jar!的方式访问import文件。- jdk有xml-apis及其实现,可是尝试覆盖其
XMLSchemaMessages.properties
以便自定义提示语句时出现问题,便引用了xml-apis
及xercesImpl
,覆盖了org.apache.xerces.impl.msg
包下的properties文件。- 上述代码能够完成多schema文件的校验,需保证xsd都在相同路径。若不在同一位置,可参考连接中博客的方式,实现SchemaFactory解析shcema的处理操做。