使用dom4j进行校验时是将整个文件读入内存,处理大文件内存溢出。
使用xsd schema,通过stax读取xml大文件解决问题。
import java.io.*;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import javax.xml.XMLConstants;
import org.xml.sax.SAXParseException;
public class XMLValidator {
public static void validate(String sourceFilePath, String schemaFilePath) throws Exception {
// 1. Lookup a factory for the W3C XML Schema language
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
// 2. Compile the schema.
// Here the schema is loaded from a java.io.File, but you could use
// a java.net.URL or a javax.xml.transform.Source instead.
File schemaLocation = new File(schemaFilePath);
Schema schema = factory.newSchema(schemaLocation);
// 3. Get a validator from the schema.
Validator validator = schema.newValidator();
// 使用javax.stream 读取源文件
Source source = new StreamSource(sourceFilePath);
try {
validator.validate(source);
} catch (SAXParseException ex) {
System.out.println(ex.getMessage());
//可获取文件、行号、具体原因
}
}
}
内部实现采用apache xerces
com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator fSchemaValidator;
http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html
之前遇到问题:
在处理镜像大文件时需要按规则分解生成小文件并进行校验,channel+stax有效提高了读取300M以上XML文件并写入的效率。开始在使用dom4j写xml时效率难以忍受,主要原因是在按节点写入时的校验过程影响效率。后来通过file channel+stax方式读取xml,写入文件(不做格式校验,当做txt文件来写)效率非常高,可以满足需求。