前段时间因项目需要和外部进行数据交换,采用XML为数据交换载体。这样就需要在数据交换前调用schema进行数据合法性校验,先通过XMLSpy工具制定好XSD验证文件(XMLSpy确实很方便),然后通过dom4j进行校验。废话不多说,关键代码贴下
校验器:
import java.io.IOException;
import org.dom4j.io.SAXReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class Validateor {
public static SAXReader reader;
private static EntityResolver aresolve;//校验器
private static Validateor validateor=Validateor.getInstance();
static{
if(aresolve==null){
aresolve=new EntityResolver(){
public InputSource resolveEntity(String arg0, String arg1)
throws SAXException, IOException {
Resource resource =new ClassPathResource("com/***/***/***/***/a.xsd");
return new InputSource(resource.getInputStream());
}
};
}
if(reader==null){
reader=new SAXReader(true);
}
try {
//符合的标准
reader.setFeature("http://apache.org/xml/features/validation/schema", true);
reader.setFeature("http://apache.org/xml/features/validation/schema-full-checking",true);
reader.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage","http://www.w3.org/2001/XMLSchema");
} catch (SAXException e1) {
System.err.println("设置校验参数错误");;
}
}
private Validateor(){
}
public static SAXReader valid(String type){
//根据不同的类型读取相应的校验文件,此处删除了一些业务代码
if("01".equals(type)) reader.setEntityResolver(aresolve);
return reader;
}
synchronized public static Validateor getInstance(){
if(validateor==null){
validateor=new Validateor();
}
return validByXsd;
}
}
校验方法
public Object validXmlData(String filePath, String type) {
InputStreamReader streamReader=null;
try {
FileInputStream in = new FileInputStream(new File(filePath));
//编码格式统一处理,支持非utf-8格式的声明文件
streamReader= new InputStreamReader(in,"UTF-8");
} catch (Exception e) {
return "读取文件出现异常:"+e.getLocalizedMessage();
}
try {
Document dateXml=Validateor.valid(type).read(streamReader);
dateXml.setXMLEncoding("UTF-8");
return dateXml;
} catch (DocumentException e) {
return "文件校验失败:"+e.getLocalizedMessage();
}
}
Schema
用XMLSpy生成,只把需要注意的命名空间贴上
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.xxx.com" targetNamespace="http://www.xxx.com" elementFormDefault="qualified">
验证的XML
<account-data
xmlns="http://www.xxx.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.xxx.com a.xsd">
注意在XML的声明处: xsi:schemaLocation="http://www.xxx.com a.xsd"> 后面的a.xsd就是前面的schema名字,与前面的中间http://www.xxx.com 之间有空格。
PS:加上命名空间的XML不能直接用dom4j的selectNodes之类的API得到节点,需要对XPATH进行设置,用dom4j的elements方法比较简单些,具体API可以翻阅dom4j的文档(如无特别要求还是不加命名空间的比较简便,校验方法都是一样的,但取值比较方便)。得到节点的属性值可以用:node.valueOf("@属性名")来取得。