最近項目須要使用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的處理操做。