最近项目需要使用xsd对xml进行预校验,于是封装了一个工具类,来完成校验工作。
完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| 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 {
static{ System.setProperty("jdk.xml.maxOccurLimit", "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 {
} @Override public void fatalError(SAXParseException exception) throws SAXException {
} @Override public void error(SAXParseException exception) throws SAXException {
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()); } } }
|
该代码应该可以完成一般需求。不过需要注意以下问题:
- 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的处理操作。