JDK中的javax.xml包中有能進行schema校驗的類庫,但隻能傳回true或false,無法給出确切的錯誤資訊。
Dom4j中給出了幾種schema校驗的思路,本文實作其中一種。
Dom4j在github上的文檔位址是:https://github.com/dom4j/dom4j/wiki/Cookbook
校驗時,能夠記錄schema中所有不比對的錯誤,但首先要保證xmL格式正确,否則隻輸出格式錯誤資訊。
pom檔案:
<dependencies>
<!-- dom4j XML工具包 -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.4</version>
</dependency>
</dependencies>
主要代碼:
public static void validateXMLByXSD() {
// 從類路徑下讀取檔案
URL xmlFileName = SchemaValidateUtil.class.getClassLoader().getResource("test.xml");
// 輸出為file:/D:/MyWorkSpace/FirstWorkSpace/validate-xml-test/target/classes/test_schema.xsd
String xsdFileName = SchemaValidateUtil.class.getClassLoader().getResource("test_schema.xsd").toString();
try {
//建立預設的XML錯誤處理器
XMLErrorHandler errorHandler = new XMLErrorHandler();
//擷取基于 SAX 的解析器的執行個體
SAXParserFactory factory = SAXParserFactory.newInstance();
//解析器在解析時驗證 XML 内容。
factory.setValidating(true);
//指定由此代碼生成的解析器将提供對 XML 名稱空間的支援。
factory.setNamespaceAware(true);
//使用目前配置的工廠參數建立 SAXParser 的一個新執行個體。
SAXParser parser = factory.newSAXParser();
//建立一個讀取工具
SAXReader xmlReader = new SAXReader();
//擷取要校驗xml文檔執行個體
Document xmlDocument = (Document) xmlReader.read(xmlFileName);
//設定 XMLReader 的基礎實作中的特定屬性。核心功能和屬性清單可以在 [url]http://sax.sourceforge.net/?selected=get-set[/url] 中找到。
parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource",xsdFileName);
//建立一個SAXValidator校驗工具,并設定校驗工具的屬性
SAXValidator validator = new SAXValidator(parser.getXMLReader());
//設定校驗工具的錯誤處理器,當發生錯誤時,可以從處理器對象中得到錯誤資訊。
validator.setErrorHandler(errorHandler);
//校驗
validator.validate(xmlDocument);
// 錯誤輸出方式1
XMLWriter writer = new XMLWriter(OutputFormat.createPrettyPrint());
//如果錯誤資訊不為空,說明校驗失敗,列印錯誤資訊
if (errorHandler.getErrors().hasContent()) {
System.out.println("XML檔案通過XSD檔案校驗失敗!");
writer.write(errorHandler.getErrors());
} else {
System.out.println("XML檔案通過XSD檔案校驗成功!");
}
// 錯誤輸出方式2
System.out.println();
StringBuilder errorMsg = new StringBuilder();
if (errorHandler.getErrors().hasContent()) {
List<Element> elements = errorHandler.getErrors().elements();
for (Element element : elements) {
String line = String.valueOf(Integer.parseInt(element.attributeValue("line")) - 1);
String text = element.getText();
errorMsg.append("(第 " + line + "行出現錯誤) " + text+"\r\n");
}
errorMsg.append("XML檔案通過XSD檔案校驗失敗!");
System.out.println(errorMsg.toString());
}else {
System.out.println("XML檔案通過XSD檔案校驗成功!");
}
} catch (Exception ex) {
System.out.println("XML檔案: " + xmlFileName + " 通過XSD檔案:" + xsdFileName + "檢驗失敗。/n原因: " + ex.getMessage());
ex.printStackTrace();
}
}