me.icymint.libra.xml.AbstractXmlParser Maven / Gradle / Ivy
package me.icymint.libra.xml;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.SAXValidator;
import org.dom4j.io.XMLWriter;
import org.dom4j.util.XMLErrorHandler;
import org.xml.sax.SAXException;
public abstract class AbstractXmlParser implements XmlParser {
private final URL xsd;
private final String rootName;
private final String nameSpace;
private final String xsdLocation;
protected AbstractXmlParser(URL xsd, String rootName, String nameSpace,
String xsdLocation) {
this.xsd = xsd;
this.rootName = rootName;
this.nameSpace = nameSpace;
this.xsdLocation = xsdLocation;
}
protected Document filter(Document doc) {
return doc;
}
/**
* 初始化头部文档
*/
protected Element initHeader() {
DocumentFactory df = DocumentFactory.getInstance();
Element root = df.createElement(rootName, nameSpace);
Namespace ns = df.createNamespace("xsi",
"http://www.w3.org/2001/XMLSchema-instance");
root.addAttribute(df.createQName("schemaLocation", ns), nameSpace + " "
+ xsdLocation);
return root;
}
protected abstract T parser(Element root, V properties)
throws XmlParserException;
@Override
public T parser(InputStream is, V properties) throws XmlParserException {
Element root = this.validate0(is);
return root == null ? null : parser(root, properties);
}
protected void save(Element root, OutputStream os)
throws XmlParserException {
/**
* 保存。
*/
XMLWriter x;
try {
OutputFormat of = OutputFormat.createPrettyPrint();
of.setEncoding("UTF-8");
of.setTrimText(false);
of.setIndent(" ");
x = new XMLWriter(os, of);
Document doc = DocumentFactory.getInstance().createDocument(root);
x.write(filter(doc));
} catch (UnsupportedEncodingException e1) {
throw new XmlParserException(e1);
} catch (IOException e1) {
throw new XmlParserException(e1);
}
}
protected abstract void store(Element root, T t) throws XmlParserException;
@Override
public void store(T t, OutputStream os) throws XmlParserException {
Element root = initHeader();
store(root, t);
save(root, os);
}
@Override
public boolean validate(InputStream xml) throws XmlParserException {
return this.validate0(xml) != null;
}
private Element validate0(InputStream xml) throws XmlParserException {
XMLErrorHandler errorHandler = new XMLErrorHandler();
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
try {
SAXParser parser = factory.newSAXParser();
SAXReader xmlReader = new SAXReader();
xmlReader.setEncoding("UTF-8");
Document xmlDocument = xmlReader.read(xml);
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",
xsd.openStream());
SAXValidator validator = new SAXValidator(parser.getXMLReader());
validator.setErrorHandler(errorHandler);
validator.validate(xmlDocument);
XMLWriter writer = new XMLWriter(OutputFormat.createPrettyPrint());
if (errorHandler.getErrors().hasContent()) {
writer.write(errorHandler.getErrors());
return null;
} else {
return xmlDocument.getRootElement();
}
} catch (ParserConfigurationException e) {
throw new XmlParserException(e);
} catch (SAXException e) {
throw new XmlParserException(e);
} catch (DocumentException e) {
throw new XmlParserException(e);
} catch (UnsupportedEncodingException e) {
throw new XmlParserException(e);
} catch (IOException e) {
throw new XmlParserException(e);
}
}
}