Проверка по схеме с помощью JAXB

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

У меня есть XML-схема, которую я использовал с xjc для создания своей привязки JAXB. Это прекрасно работает, когда XML правильно сформирован. К сожалению, он также не жалуется, когда XML не очень хорошо сформирован. Я не могу понять, как правильно выполнить полную проверку схемы, когда пытаюсь разобрать XML-файл.

Мне удалось использовать ValidationEventCollector для обработки событий, который работает для ошибок синтаксического анализа XML, таких как несоответствующие теги, но не вызывает никаких событий, когда есть тег, который требуется, но полностью отсутствует.

Из того, что я видел, проверка может быть выполнена снова в схеме, но вы должны знать путь к схеме, чтобы передать ее в метод setSchema (). У меня проблема в том, что путь к схеме хранится в заголовке XML, и я не могу знать, во время выполнения, где схема будет. Вот почему он хранится в файле XML:

<?xml version="1.0" encoding="utf-8"?>
<DDSSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/a/big/long/path/to/a/schema/file/DDSSettings.xsd">
<Field1>1</Field1>
<Field2>-1</Field2>

...так далее

Каждый пример, который я вижу, использует setValidating (true), который теперь устарел, поэтому выдает исключение.

Это код Java, который у меня есть, который, кажется, выполняет только проверку XML, а не проверку схемы:

try {
    JAXBContext jc = new JAXBContext() {
        private final JAXBContext jaxbContext = JAXBContext.newInstance("blah");

        @Override
        public Unmarshaller createUnmarshaller() throws JAXBException {
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            ValidationEventCollector vec = new ValidationEventCollector() {
                @Override
                public boolean handleEvent(ValidationEvent event) throws RuntimeException {
                    ValidationEventLocator vel = event.getLocator();
                    if (event.getSeverity() == event.ERROR || event.getSeverity() == event.FATAL_ERROR) {
                        String error = "XML Validation Exception:  " + event.getMessage() + " at row: " + vel.getLineNumber() + " column: " + vel.getColumnNumber();
                        System.out.println(error);
                    }
                    m_unmarshallingOk = false;
                    return false;
                }
            };
            unmarshaller.setEventHandler(vec);

            return unmarshaller;
        }

        @Override
        public Marshaller createMarshaller() throws JAXBException {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        @SuppressWarnings("deprecation")
        public Validator createValidator() throws JAXBException {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    };

    Unmarshaller unmarshaller = jc.createUnmarshaller();
    m_ddsSettings = (com.ultra.DDSSettings)unmarshaller.unmarshal(new File(xmlfileName));
} catch (UnmarshalException ex) {
    Logger.getLogger(UniversalDomainParticipant.class.getName()).log(
    Level.SEVERE,
    null, ex);
} catch (JAXBException ex) {
    Logger.getLogger(UniversalDomainParticipant.class.getName()).log(
    Level.SEVERE,
    null, ex);
}

Итак, как правильно сделать эту проверку? Я ожидал, что в сгенерированных JAXB классах будет метод validate (), но я думаю, это было бы слишком просто для Java.

Ответы на вопрос(2)

Ваш ответ на вопрос