import java.io.File;
import java.io.IOException;
import javax.xml.transform.Source;
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.SAXException;
public class ValidateXML {
/**
*
*/
public ValidateXML(){
}
public boolean Validatexml(String xsdpath,String xmlpath) throws SAXException,IOException{
//建立schema工厂
SchemaFactory schemaFactory=SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema ");
//建立验证文档文件对象,利用此文件对象所封装的文件进行schema验证
File schemaFile=new File(xsdpath);
//利用schema工厂,接收验证文档文件对象生成Schema对象
Schema schema=schemaFactory.newSchema(schemaFile);
//通过Schema产生针对于此Schema的验证器,利用schenaFile进行验证
Validator validator=schema.newValidator();
//得到验证的数据源
Source source=new StreamSource(xmlpath);
//开始验证,成功输出success!!!,失败输出fail
try{
validator.validate(source);
}catch(Exception ex){
ex.printStackTrace();
}
return true;
本文介绍了使用XML Schema文件(即.xsd)文件对XML文件的验证,早期的XML文件是由DTD进行定义的,但是后来转为由XML Schema进行定义,有时为了对一个xml文档进行验证,可能要根据xml解析器进行多次的获取进行判断,加之xml的元素的值类型又有很多种不同的约 束,所以判断起来更加困难。
一般来说,一个xml文档都有一个与之对应的xsd文件来定义它,例如下面的xml文档:<?xml version="1.0" encoding="UTF-8"?><ccc:Person xmlns:ccc="http://localhost/example"> <ccc:Name>Hello</ccc:Name></ccc:Person>就可以通过以下的xsd文件进行定义:<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://localhost/example" elementFormDefault="qualified" xmlns:tns=" http://localhost/example"> <xsd:element name="Person"> <xsd:complexType> <xsd:choice> <xsd:element name="Name" type="xsd:string" /> <xsd:element name="Email" type="xsd:string" /> </xsd:choice> </xsd:complexType> </xsd:element></xsd:schema> 这个xsd简单的定义了一个元素Person,Person元素包含Name或者Email两个元素之一,两个元素必须出现一个,且出现的次数为一次。(对于XML Schema语法的学习,请参考W3C方文档),这个元素的名称空间为http://localhost/example,并且每个元素必须使用名称空间进行唯一约束。通过对这个xsd的了解,可以知道示例中的xml文件为正确的,或者说符合xsd定义的文档。当然下面的文档也是正确的:<?xml version="1.0" encoding="UTF-8"?><ccc:Person xmlns:ccc="http://localhost/example"> <ccc:Email>hello@hi.com</ccc:Email></ccc:Person> 而下面的文档就是错误的了:<?xml version="1.0" encoding="UTF-8"?><ccc:Person xmlns:ccc="http://localhost/example"> <ccc:Name>Hello</ccc:Name><ccc:Email>hello@hi.com</ccc:Email></ccc:Person>[多了一个元素]或者<?xml version="1.0" encoding="UTF-8"?><ccc:Person xmlns:ccc="http://localhost/example"> <ccc:Name><A>Hello</A></ccc:Name></ccc:Person>[包含了子元素<A>]还有诸如元素名字不正确,元素名称空间不正确等等,如果使用SAX,DOM或者JDOM,DOM4J之类的解析器判断合法性,如果像示例这样大小的文件还勉强可以,但是一旦上千行的xml文件,可能谁都不愿意去判断了。这里我们指的错误与否不设计XML文件的格式,比如缺少结束tag之类的错误。(因为通常这类错误可以通过编辑器就可以发现)下面言归正传,讲解如何通过编程实现xsd验证xml。SchemaValidate.javapackage org.ly.validate; import java.io.ByteArrayInputStream;import java.io.FileNotFoundException;import java.io.IOException; import javax.xml.XMLConstants;import javax.xml.stream.FactoryConfigurationError;import javax.xml.stream.XMLInputFactory;import javax.xml.stream.XMLStreamException;import javax.xml.stream.XMLStreamReader;import javax.xml.transform.Source;import javax.xml.transform.stream.StreamSource;import javax.xml.validation.Schema;import javax.xml.validation.SchemaFactory;import javax.xml.validation.Validator; import org.apache.axiom.om.OMElement;import org.apache.axiom.om.impl.builder.StAXOMBuilder;import org.xml.sax.SAXException; public class SchemaValidate { /** * Validate the xml file with XML Schema file * * @return true:if the xml is valid false:if the xml is invalid * @throws SAXException * @throws IOException */ public static boolean validate(String schemaLocaltion, OMElement request) throws SAXException, IOException { //获取Schema工厂类,//这里的XMLConstants.W3C_XML_SCHEMA_NS_URI的值就是://http://www.w3.org/2001/XMLSchema SchemaFactory factory = SchemaFactory .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // Schema实例 Schema schema = null; //获取xsd文件,以流的方式读取到Source中 //xsd文件的位置相对于类文件位置/***例如类名为:org.ly.validate.SchemaValidate,则xsd文件的位置*应该是相对于org这个目录的。*/ Source schemaSource = new StreamSource(SchemaValidate.class .getResourceAsStream(schemaLocaltion)); //实例化Schema对象 schema = factory.newSchema(schemaSource); //这里是将一个DOM树对象转换成流对象,以便对DOM树对象验证 //如果是对XML文件进行验证,用FileInputStream即可String input = request.toString(); ByteArrayInputStream bais = new ByteArrayInputStream(input .getBytes(“UTF-8”)); // 获取验证器,验证器的XML Schema源就是之前创建的Schema Validator validator = schema.newValidator(); Source source = new StreamSource(bais); // 执行验证 validator.validate(source); return true; } /** * get OMElement soap request from specified xml file. * * @param request * @return * @throws FileNotFoundException * @throws XMLStreamException * @throws FactoryConfigurationError */ public static OMElement getRequest(String filePath) throws FileNotFoundException, XMLStreamException, FactoryConfigurationError { XMLStreamReader reader = XMLInputFactory.newInstance() .createXMLStreamReader( SchemaValidate.class.getResourceAsStream(filePath)); StAXOMBuilder builder = new StAXOMBuilder(reader); OMElement requestMessage = builder.getDocumentElement(); return requestMessage; } public static void main(String[] args) throws SAXException, IOException, XMLStreamException, FactoryConfigurationError { System.out.println(validate("/Person.xsd", getRequest("/Person.xml"))); }}如果验证通过,则打印true消息,如果验证失败,则打印异常消息,例如验证以下XML文件:<?xml version="1.0" encoding="UTF-8"?><ccc:Person xmlns:ccc="http://localhost/example"> <ccc:Name>Hello</ccc:Name> <ccc:Name>Hello</ccc:Name></ccc:Person>