JAXB: при использовании схемы XML (.xsd) для проверки файла XML, если проверка не удалась, могу ли я узнать, какой тег XML вызвал это? - PullRequest
12 голосов
/ 12 декабря 2011

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

[org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'City'. One of '{Address1}' is expected.]

В приведенном выше примере это не удалось, потому что мне не хватает тега Address1. У меня вопрос Когда проверка не пройдена, могу ли я узнать, какой тег вызвал ошибку? Это потому, что мне нужно обрабатывать эти ошибки по-разному для каждого важным пропущенного тега. Прямо сейчас моя мысль

FileInputStream inputStream = null;
try{
    SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = sf.newSchema(new File(config.getXmlSchema()));
    JAXBContext context = JAXBContext.newInstance(PackageLabel.class);
    Unmarshaller unmarshaller = context.createUnmarshaller();
    unmarshaller.setSchema(schema);
    inputStream = new FileInputStream(xmlFile);
    pl = (PackageLabel) unmarshaller.unmarshal(inputStream);
} catch (JAXBException e) {
    if(pl.getAddress1() == null){
         System.out.println("Invalid Mailing Address");
    }
    //EDIT: CANNOT DO THIS, SINCE pl  IS NULL AT THIS POINT
    //Some more logics on how to handle important missing-tags
    ...
}finally{
    if(inputStream != null) inputStream.close();
}  

Однако я не думаю, что написание логики внутри catch clause является правильным. Любой совет?

EDIT

Я следовал идее Balaise, и ниже приведено событие, которое я получил, когда в XML отсутствовал адрес1

EVENT
SEVERITY:  2
MESSAGE:  cvc-complex-type.2.4.a: Invalid content was found starting with element 'City'. One of '{Address1}' is expected.
LINKED EXCEPTION:  org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'City'. One of '{Address1}' is expected.
LOCATOR
 LINE NUMBER:  4
 COLUMN NUMBER:  11
 OFFSET:  -1
 OBJECT:  null
 NODE:  null
 URL:  null

Тем не менее, NODE и OBJECT равны нулю, я не могу дополнительно выяснить, что вызвало исключение, если я не проанализирую исключение, как я и просил изначально.

Ответы [ 3 ]

7 голосов
/ 12 декабря 2011

Вы можете использовать для этого JAXB ValidationEventHandler.Затем можно установить реализацию для экземпляров Marshaller и Unmarshaller:

package blog.jaxb.validation;

import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;

public class MyValidationEventHandler implements ValidationEventHandler {

    public boolean handleEvent(ValidationEvent event) {
        System.out.println("\nEVENT");
        System.out.println("SEVERITY:  " + event.getSeverity());
        System.out.println("MESSAGE:  " + event.getMessage());
        System.out.println("LINKED EXCEPTION:  " + event.getLinkedException());
        System.out.println("LOCATOR");
        System.out.println("    LINE NUMBER:  " + event.getLocator().getLineNumber());
        System.out.println("    COLUMN NUMBER:  " + event.getLocator().getColumnNumber());
        System.out.println("    OFFSET:  " + event.getLocator().getOffset());
        System.out.println("    OBJECT:  " + event.getLocator().getObject());
        System.out.println("    NODE:  " + event.getLocator().getNode());
        System.out.println("    URL:  " + event.getLocator().getURL());
        return true;
    }

}

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

2 голосов
/ 27 декабря 2011

Не существует правильно сформированного решения того, что вы спрашиваете через JAXB. JAXB обеспечивает поддержку для проверки исходного XML-кода по схеме, в которой приводятся значения - true или false. Концепция заключается в том, что если XML является недействительным, вы не должны продолжать дальше.

2 голосов
/ 22 декабря 2011

Следующее может работать (я еще не кодировал). Вы можете создать StAX XMLStreamReader для вашего XML-ввода. Затем отмените маршалинг с помощью Unmarshaller с установленной на нем схемой, чтобы включить валидацию. В случае возникновения ошибки демонтаж будет остановлен. Затем вы можете проверить, в каком событии находится XMLStreamReader, чтобы увидеть, где произошла ошибка.

...