Проверка против схемы с JAXB

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

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

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

Из того, что я видел, что проверка может быть сделана againsta схема, но необходимо знать путь к схеме для передачи его в setSchema () метод. Проблема, которую я имею, состоит в том, что путь к схеме хранится в заголовке XML, и я не могу knwo во время выполнения, где схема будет. Который является, почему это хранится в 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 (верный), который теперь удерживается от использования, поэтому выдает исключение.

Это - код 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 генерировал классы, но я предполагаю, что это было бы слишком просто для Java.

12
задан ndsmyter 8 April 2014 в 09:22
поделиться

2 ответа

Хорошо, я нашел решение. Использование фабрики схем для создания схемы, но без указания файла схемы, заставляет ее работать с noNamespaceSchemaLocation, указанным в XML-файле.

Итак, в приведенный выше код было добавлено следующее:

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setSchema(schema);
m_ddsSettings = (com.ultra.DDSSettings)unmarshaller.unmarshal(new File(xmlfileName));

Позор, на поиск ответа на который ушло почти 24 часа!

Документация javadoc для SchemaFactory.newSchema () говорит:

Для схемы XML этот метод создает объект схемы , который выполняет проверку , используя подсказки местоположения, указанные в документах .

Возвращенный объект схемы предполагает , что если документы ссылаются на один и тот же URL в подсказках расположения схемы, они всегда будут преобразовываться в одну и ту же схему документ. Этот asusmption позволяет реализациям повторно использовать проанализированные результаты документов схемы, так что несколько проверок по одной и той же схеме будут выполняться быстрее.

15
ответ дан 2 December 2019 в 20:16
поделиться

Насколько я знаю, вам просто нужно установить схему с помощью Marshaller.setSchema() на схему, созданную SchemaFactory из вашего DDSSettings.xsd. Это включит валидацию.

1
ответ дан 2 December 2019 в 20:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: