本文介绍了使用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
之类的错误。(因为通常这类错误可以通过编辑器就可以发现)
SchemaValidate.java
package 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
>