package sax.parsing; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import org.dom4j.DocumentException; import org.dom4j.io.SAXReader; import org.dom4j.io.SAXValidator; import org.testng.annotations.Test; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.XMLReaderFactory; public class ErrorProcessor extends DefaultHandler { @Override public void warning(SAXParseException exception) throws SAXException { System.out.println("触发警告:"); System.err.println("warning: " + getLocationString(exception) + ": " + exception.getMessage()); } @Override public void error(SAXParseException exception) throws SAXException { System.out.println("触发错误:"); System.err.println("error: " + getLocationString(exception) + ": " + exception.getMessage()); } @Override public void fatalError(SAXParseException exception) throws SAXException { System.out.println("触发致命错误:"); System.err.println("fatal error: " + getLocationString(exception) + ": " + exception.getMessage()); } private String getLocationString(SAXParseException ex) { StringBuffer buffer = new StringBuffer(); String publicId = ex.getPublicId(); if (publicId != null) { buffer.append(publicId); buffer.append(" "); } String systemId = ex.getSystemId(); if (systemId != null) { buffer.append(systemId); buffer.append(':'); } buffer.append(ex.getLineNumber()); buffer.append(':'); buffer.append(ex.getColumnNumber()); return buffer.toString(); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("</" + qName + ">"); } /** * 在DOM文件构建工厂中设置校验Schema文件 * @throws IOException * @throws SAXException * @throws ParserConfigurationException */ @Test public void parseWithSchema() throws SAXException, IOException, ParserConfigurationException { System.out.println("========== parseWithSchema() start ==============="); SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = schemaFactory.newSchema(new File("src/students.xsd")); DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); builderFactory.setSchema(schema); DocumentBuilder builder = builderFactory.newDocumentBuilder(); builder.setErrorHandler(new ErrorProcessor()); Document doc = builder.parse("src/students.xml"); System.out.println("========== parseWithSchema() end ==============="); } @Test public void read() throws FileNotFoundException, IOException, SAXException { System.out.println("========== read() start (仅语法校验) ==============="); XMLReader xmlReader = XMLReaderFactory.createXMLReader(); xmlReader.setFeature("http://xml.org/sax/features/validation", true); xmlReader.setFeature("http://xml.org/sax/features/namespaces", true); xmlReader.setErrorHandler(new ErrorProcessor()); xmlReader.parse(new InputSource(new FileInputStream("src/students.xml"))); System.out.println("========== read() end ==============="); } @Test public void saxValidate() throws ParserConfigurationException, SAXException, DocumentException, FileNotFoundException, IOException { System.out.println("========== saxValidate() start ==============="); SAXParserFactory parserFactory = SAXParserFactory.newInstance(); parserFactory.setValidating(true); // 等价于 xmlReader.setFeature("http://xml.org/sax/features/validation", true); parserFactory.setNamespaceAware(true); // 等价于 reader.setFeature("http://xml.org/sax/features/namespaces",true); SAXParser parser = parserFactory.newSAXParser(); 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", "file:/D:/eclipse-luna-jee/workspace/xsl_trans/src/students.xsd"); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setErrorHandler(new ErrorProcessor()); // 错误时触发 //xmlReader.setContentHandler(new ErrorProcessor()); // 标签开始、结束等事件时触发 xmlReader.parse(new InputSource(new FileInputStream("src/students.xml"))); System.out.println("========== saxValidate() end ==============="); } @Test public void dom4jValidate() throws ParserConfigurationException, SAXException, DocumentException, FileNotFoundException, IOException { System.out.println("========== dom4jValidate() start ==============="); SAXParserFactory parserFactory = SAXParserFactory.newInstance(); parserFactory.setValidating(true); // 等价于 xmlReader.setFeature("http://xml.org/sax/features/validation", true); parserFactory.setNamespaceAware(true); // 等价于 reader.setFeature("http://xml.org/sax/features/namespaces",true); SAXParser parser = parserFactory.newSAXParser(); 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", "file:/D:/eclipse-luna-jee/workspace/xsl_trans/src/students.xsd"); XMLReader xmlReader = parser.getXMLReader(); /* * dom4j的校验处理过程 * org.dom4j.io.SAXReader * org.dom4j.Document * org.dom4j.io.SAXValidator */ SAXReader reader = new SAXReader(); org.dom4j.Document doc = reader.read(new File("src/students.xml")); SAXValidator validator = new SAXValidator(xmlReader); validator.setErrorHandler(new ErrorProcessor()); validator.validate(doc); System.out.println("========== dom4jValidate() end ==============="); } }
输出:
========== parseWithSchema() start ===============
error: file:///D:/eclipse-luna-jee/workspace/xsl_trans/src/students.xml:4:41: cvc-complex-type.3.2.2: Attribute 'attr_test' is not allowed to appear in element 'student'.触发错误:
触发错误:
error: file:///D:/eclipse-luna-jee/workspace/xsl_trans/src/students.xml:10:40: cvc-complex-type.2.4.a: Invalid content was found starting with element 'elem_test1'. One of '{student}' is expected.
========== parseWithSchema() end ===============
========== read() start (仅语法校验) ===============
触发错误:
error: 3:10: Document is invalid: no grammar found.
触发错误:
error: 3:10: Document root element "students", must match DOCTYPE root "null".
========== read() end ===============
========== saxValidate() start ===============
触发错误:
error: 4:41: cvc-complex-type.3.2.2: Attribute 'attr_test' is not allowed to appear in element 'student'.
触发错误:
error: 10:40: cvc-complex-type.2.4.a: Invalid content was found starting with element 'elem_test1'. One of '{student}' is expected.
========== saxValidate() end ===============
========== dom4jValidate() start ===============
触发错误:
error: file:///D:/eclipse-luna-jee/workspace/xsl_trans/src/students.xml:3:41: cvc-complex-type.3.2.2: Attribute 'attr_test' is not allowed to appear in element 'student'.
触发错误:
error: file:///D:/eclipse-luna-jee/workspace/xsl_trans/src/students.xml:9:39: cvc-complex-type.2.4.a: Invalid content was found starting with element 'elem_test1'. One of '{student}' is expected.
========== dom4jValidate() end ===============
students.xml
<?xml version="1.0" encoding="utf-8" ?> <students> <student sn="01" attr_test="errorAttr"><!-- 在student与name父子元素节点之间的是一个文本节点('\n\t\t') --> <name>张三</name> <age>18</age> <score>100</score> </student> <elem_test1 attr_test1="errorAttr1" /> <student sn="02"> <name>lisi</name> <age>20</age> <score>100</score> </student> <elem_test2 attr_test1="errorAttr2" /> </students>
students.xsd
<?xml version="1.0" encoding="utf-8" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="students"> <xs:complexType> <xs:sequence> <xs:element name="student" type="studentType" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="studentType"> <xs:sequence> <xs:element name="name" type="xs:token" /> <xs:element name="age" type="xs:positiveInteger" /> <xs:element name="score" type="xs:float" /> </xs:sequence> <xs:attribute name="sn" type="xs:token" /> </xs:complexType> </xs:schema>