Проблема проверки схемы Jaxb 2.0 - PullRequest
3 голосов
/ 01 февраля 2011

Я работаю с Jaxb 2.x и пытался проверить документ XML с данным XSD, используя следующий учебник

Ссылка на учебник

ее кодя написал

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) {

, и мой класс 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();

    }
                       }

}

Код предупреждения и фатальный удален, теперь он проверяет XML с помощью XSD, но показывает только первый встреченныйошибка, пока я хочу распечатать на консоли все ошибки и предупреждения на консоли

Я не уверен, где я делаю неправильно, любая помощь в этом будет полезна

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>

, а 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>

, что, как я полагаю после некоторых исследований и разработок, состоит в том, что существует некоторая проблема со структурой XSD или сгенерированным XMLно я не уверен в этом

Ответы [ 2 ]

3 голосов
/ 03 февраля 2011

Существует несколько подходов, которые вы можете использовать для проверки вашего XML-документа по XML-схеме.

javax.xml.validation APIs

Первый - использоватьAPI-интерфейсы javax.xml.validation для проверки вашего документа по схеме XML без JAXB.

<?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>

и 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>

со следующим демонстрационным кодом:

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);
        }

    }

}

Будет выдан следующий вывод с несколькими ошибками:

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

API-интерфейсы 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;
        }

    }

}

Для получения дополнительной информации:

0 голосов
/ 01 февраля 2011

Я предполагаю, что, возможно, сообщалось fatalError. Вы не предоставили такую ​​информацию в своем вопросе. Если это так, вы можете прочитать объяснение вашей проблемы в javadoc ErrorHandler:

Обратите внимание, однако, что нет требование, чтобы парсер продолжал сообщить о дополнительных ошибках после позвоните по номеру fatalError. Другими словами, класс драйвера SAX может выдать исключение после сообщения любого fatalError.

Я надеюсь, что это может объяснить вашу проблему.

Редактировать 1: После того, как вы опубликовали свою схему, я думаю, что вас это беспокоит. Валидатор сообщает об одной ошибке на неправильный элемент. В вашем случае это:

<xs:element name="destination" type="Destination"/>

Ошибка будет что-то вроде (указывает на отсутствие 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.

Он не сообщает о множественных ошибках, поскольку для каждого сложного типа существует только один отчет об ошибках. Если вы измените свой сложный тип следующим образом:

<xs:all>

Вы можете получить другое сообщение, но снова одно:

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.

Если вы измените свою схему так, чтобы она принимала несколько элементов destination, вы можете получить 1 сообщение об ошибке на элемент.

Ура!

...