java Jaxb 2.0 Schema 验证问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4864681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jaxb 2.0 Schema validation problem
提问by Umesh Awasthi
I am working with Jaxb 2.x and was trying to validate XML document with the given XSD using the following tutorial
我正在使用 Jaxb 2.x 并尝试使用以下教程使用给定的 XSD 验证 XML 文档
hers is the code i have written
她是我写的代码
unmarshaller.setSchema(schema);
SAXSource source = new SAXSource(new InputSource(xmlFileLocation));
Validator validator = schema.newValidator();
validator.setErrorHandler(new XMLErrorHandler<Object>());
try {
validator.validate(source);
} catch (SAXException e) {
and my XMLErrorHanlder class have following signature
和我的 XMLErrorHanlder 类具有以下签名
public class XMLErrorHandler<T> implements ErrorHandler {
public void error(SAXParseException exception) throws SAXException {
xmlUnmarshaller.setValidationFlag(true);
log.error(
"Line:Col[" + exception.getLineNumber()
+ ":" + exception.getColumnNumber()
+ "]:" + exception.getMessage());
exception.printStackTrace();
}
}
}
code for warning and fatal has been removed now its validating the XML with XSD but it only showing the first encountered error while i want to get print on colsole all errors and warning on console
警告和致命的代码已被删除,现在它使用 XSD 验证 XML,但它只显示第一个遇到的错误,而我想在 colsole 上打印所有错误和控制台上的警告
i am not sure where i am doing wrong any help in this will be helpful
我不确定我哪里做错了,这方面的任何帮助都会有所帮助
Edit1here is the portion of XSD file
Edit1这里是 XSD 文件的部分
<?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="destination" type="Destination"/>
<xs:complexType name="Destination">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="destinationID" type="xs:string" minOccurs="0"/>
<xs:element name="shortDescription" type="xs:string" minOccurs="0"/>
<xs:element name="longDescription" type="xs:string" minOccurs="0"/>
<xs:element name="stateID" type="xs:string"/>
<xs:element name="typeCode" type="xs:int"/>
<xs:element name="countryCode" type="xs:string"/>
<xs:element name="categories" type="xs:string"/>
<xs:element name="transport" type="Transport" minOccurs="0" maxOccurs="1"/>
<xs:element name="cultures" type="Cultures" minOccurs="0"/>
<xs:element name="events" type="Events" minOccurs="0" maxOccurs="1"/>
<xs:element name="placesToVisit" type="PlacesToVisit" minOccurs="0" maxOccurs="1"/>
<xs:element name="contacts" type="Contact" minOccurs="0" maxOccurs="1"/>
<xs:element name="addresses" type="address" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
and the XML file is
并且 XML 文件是
<destination xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="destination.xsd">
<name>Palampur</name>
<destinationID>PLP</destinationID>
<shortDescription>shortDescription</shortDescription>
<longDescription>longDescription</longDescription>
<typeCode>0</typeCode>
<categories>categories</categories>
what my assumption after doing some R&D is that there is some issue with XSD structure or the generated XML but i am not sure abt it
在做了一些研发之后,我的假设是 XSD 结构或生成的 XML 存在一些问题,但我不确定它是否存在
采纳答案by Lachezar Balev
I assume that there might have been a fatalError
reported. You didn't provide such information in your question. If this is the case you may read the explanation of your problem in the javadoc of ErrorHandler
:
我认为可能有fatalError
报道。您没有在问题中提供此类信息。如果是这种情况,您可以在以下 javadoc 中阅读您的问题的解释ErrorHandler
:
Note, however, that there is no requirement that the parser continue to report additional errors after a call to
fatalError
. In other words, a SAX driver class may throw an exception after reporting anyfatalError
.
但是请注意,不要求解析器在调用 之后继续报告其他错误
fatalError
。换句话说,SAX 驱动程序类在报告任何fatalError
.
I hope that this might explain your trouble.
我希望这可以解释你的麻烦。
Edit 1:After you posted your schema I think I know bothers you. The validator reports a single error per wrong element. In your case this is:
编辑 1:在您发布架构后,我想我知道打扰您了。验证器会报告每个错误元素的单个错误。在您的情况下,这是:
<xs:element name="destination" type="Destination"/>
The error will be something like (indicates missing stateID):
错误将类似于(表示缺少 stateID):
Error: Line:Col[7:13]:cvc-complex-type.2.4.a: Invalid content was found starting with element 'typeCode'. One of '{stateID}' is expected.
It does not report multiple errors because there is only one error report per complex type. If you change your complex type like this:
它不会报告多个错误,因为每个复杂类型只有一个错误报告。如果您像这样更改复杂类型:
<xs:all>
You may get a different message, but again a single one:
您可能会收到不同的消息,但又是一条:
Error: Line:Col[9:15]:cvc-complex-type.2.4.b: The content of element 'destination' is not complete. One of '{stateID, countryCode}' is expected.
If you modify your schema to accept multiple destination
elements you may get 1 error message per element then.
如果您修改架构以接受多个destination
元素,则每个元素可能会收到 1 条错误消息。
Cheers!
干杯!
回答by bdoughan
There are a couple approaches you can leverage to validate your XML document against an XML schema.
有几种方法可以用来根据 XML 模式验证 XML 文档。
javax.xml.validation APIs
javax.xml.validation API
The first is to use the javax.xml.validation APIs to validate your document against an XML schema without JAXB.
第一个是使用 javax.xml.validation API 来根据没有 JAXB 的 XML 模式验证您的文档。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="destination" type="Destination"/>
<xs:complexType name="Destination">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="destinationID" type="xs:string" minOccurs="0"/>
<xs:element name="shortDescription" type="xs:string" minOccurs="0"/>
<xs:element name="longDescription" type="xs:string" minOccurs="0"/>
<xs:element name="stateID" type="xs:string"/>
<xs:element name="typeCode" type="xs:int"/>
<xs:element name="countryCode" type="xs:string"/>
<xs:element name="categories" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
and the XML document:
和 XML 文档:
<?xml version="1.0" encoding="UTF-8"?>
<destination xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="destination.xsd">
<sd></sd>
<name>Palampur</name>
<destinationID>PLP</destinationID>
<shortDescription>shortDescription</shortDescription>
<longDescription>longDescription</longDescription>
<typeCode>ZERO</typeCode>
<categories>categories</categories>
</destination>
with the following demo code:
使用以下演示代码:
import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.transform.sax.SAXSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class Demo {
public static void main(String[] args) throws Exception {
String xmlFileLocation = "src/validate/blog/input.xml";
SAXSource source = new SAXSource(new InputSource(xmlFileLocation));
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("src/validate/blog/customer.xsd"));
Validator validator = schema.newValidator();
validator.setErrorHandler(new MyErrorHandler());
validator.validate(source);
System.out.println("DONE");
}
private static class MyErrorHandler implements ErrorHandler {
public void error(SAXParseException arg0) throws SAXException {
System.out.println("ERROR");
arg0.printStackTrace(System.out);
}
public void fatalError(SAXParseException arg0) throws SAXException {
System.out.println("FATAL ERROR");
arg0.printStackTrace(System.out);
}
public void warning(SAXParseException arg0) throws SAXException {
System.out.println("WARNING ERROR");
arg0.printStackTrace(System.out);
}
}
}
Will give the following output displaying multiple errors:
将给出以下显示多个错误的输出:
ERROR
org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'sd'. One of '{name}' is expected.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.validate(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(Unknown Source)
at javax.xml.validation.Validator.validate(Unknown Source)
at validate.blog.Demo.main(Demo.java:27)
ERROR
org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'ZERO' is not a valid value for 'integer'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.validate(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(Unknown Source)
at javax.xml.validation.Validator.validate(Unknown Source)
at validate.blog.Demo.main(Demo.java:27)
ERROR
org.xml.sax.SAXParseException: cvc-type.3.1.3: The value 'ZERO' of element 'typeCode' is not valid.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.elementLocallyValidType(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processElementContent(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.validate(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(Unknown Source)
at javax.xml.validation.Validator.validate(Unknown Source)
at validate.blog.Demo.main(Demo.java:27)
DONE
JAXB APIs
JAXB API
The second approach is to validate while performing an unmarshal operation with JAXB.
第二种方法是在使用 JAXB 执行解组操作时进行验证。
import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.InputSource;
public class JaxbDemo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Destination.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("src/validate/blog/customer.xsd"));
unmarshaller.setSchema(schema);
unmarshaller.setEventHandler(new MyValidationEventHandler());
String xmlFileLocation = "src/validate/blog/input.xml";
unmarshaller.unmarshal(new InputSource(xmlFileLocation));
}
private static class MyValidationEventHandler implements ValidationEventHandler {
public boolean handleEvent(ValidationEvent arg0) {
System.out.println(arg0.getSeverity());
return true;
}
}
}
For More Information:
想要查询更多的信息: