# JAXB 模式验证

> 原文： [https://howtodoinjava.com/jaxb/xsd-schema-validation/](https://howtodoinjava.com/jaxb/xsd-schema-validation/)

了解**根据架构（xsd）**验证 XML，然后将 XML 解组到 Java 对象。 如果验证失败，还请学习**在 xml 模式验证**期间检查验证错误。

> 阅读更多：[如何从 JAXB 类生成模式](https://howtodoinjava.com/jaxb/java-class-to-xsd-eclipse/)

## 1.在 XSD 验证后将 XML 转换为 Java 对象

我们已经看到了[将 XML 文件读取到 Java 对象](https://howtodoinjava.com/jaxb/read-xml-to-java-object/)的示例。 现在让我们修改该示例，以在填充`Employee`对象之前针对 XSD 验证 XML。

```java
package com.howtodoinjava.demo;

import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.SAXException;
import com.howtodoinjava.demo.model.Employee;

public class JaxbExample 
{
	public static void main(String[] args) 
	{
		String xmlFile = "employee.xml";
		String xsdFile = "employee.xsd";

		jaxbXmlFileToObject(xmlFile, xsdFile);
	}

	private static void jaxbXmlFileToObject(String xmlFile, String xsdFile) {

		JAXBContext jaxbContext;

		try 
		{
			//Get JAXBContext
			jaxbContext = JAXBContext.newInstance(Employee.class);

			//Create Unmarshaller
			Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

			//Setup schema validator
			SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			Schema employeeSchema = sf.newSchema(new File(xsdFile));
			jaxbUnmarshaller.setSchema(employeeSchema);

			//Unmarshal xml file 
			Employee employee = (Employee) jaxbUnmarshaller.unmarshal(new File(xmlFile));

			System.out.println(employee);
		}
		catch (JAXBException | SAXException e) 
		{
			e.printStackTrace();
		}
	}
}

```

程序输出。

```java
Employee [id=1, firstName=Lokesh, lastName=Gupta, department=Department [id=101, name=IT]]

```

下面给出`employee.xml`和`employee.xsd`的含量。

```java
<employees>
	<employee id="101">
		 <name>Lokesh Gupta</name>
	    <title>Author</title>
	</employee>
	<employee id="102">
		 <name>Brian Lara</name>
	    <title>Cricketer</title>
	</employee>
</employees>

```

```java
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="department" type="department"/>

  <xs:element name="employee" type="employee"/>

  <xs:complexType name="employee">
    <xs:sequence>
      <xs:element ref="department" minOccurs="0"/>
      <xs:element name="firstName" type="xs:string" minOccurs="0"/>
      <xs:element name="id" type="xs:int" minOccurs="0"/>
      <xs:element name="lastName" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="department">
    <xs:sequence>
      <xs:element name="id" type="xs:int" minOccurs="0"/>
      <xs:element name="name" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

```

## 2.模式验证错误

针对 XML 的 XSD 验证不会总是成功。 很多时候，您会收到验证错误。 这些错误将作为[`SAXException`](https://docs.oracle.com/javase/10/docs/api/org/xml/sax/SAXException.html)抛出。 因此捕获此异常，它将具有验证失败的上下文。

例如，我已通过此更改更新了架构文件。

```java
<xs:element name="firstName" type="xs:string" minOccurs="0"/>

//to 

<xs:element name="firstName" type="xs:int" minOccurs="0"/>

```

现在来看验证错误。

```java
javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException; systemId: file:/C:/Users/lokesh/workspace/App/employee.xml; lineNumber: 7; columnNumber: 34; 
cvc-datatype-valid.1.2.1: 'Lokesh' is not a valid value for 'integer'.]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:335)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:563)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:249)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189)
at com.howtodoinjava.demo.JaxbExample.jaxbXmlFileToObject(JaxbExample.java:45)
at com.howtodoinjava.demo.JaxbExample.main(JaxbExample.java:23)
Caused by: org.xml.sax.SAXParseException; systemId: file:/C:/Users/lokesh/workspace/App/employee.xml; lineNumber: 7; columnNumber: 34; 
cvc-datatype-valid.1.2.1: 'Lokesh' is not a valid value for 'integer'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:325)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:458)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3237)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(XMLSchemaValidator.java:3152)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(XMLSchemaValidator.java:3062)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(XMLSchemaValidator.java:2140)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(XMLSchemaValidator.java:859)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.endElement(ValidatorHandlerImpl.java:584)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.endElement(ValidatingUnmarshaller.java:91)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.endElement(SAXConnector.java:165)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1782)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2973)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
... 7 more

```

将我的问题放在评论部分。

学习愉快！