簡體   English   中英

JAXB:當使用XML模式(.xsd)驗證XML文件時,如果驗證失敗,我可以知道導致它的XML標記嗎?

[英]JAXB: when using XML schema (.xsd) to validate an XML file, if validation fail, can I know which XML tag causing it?

所以當我使用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編寫邏輯是正確的。 有什么建議?

編輯

我遵循了Balaise的想法,下面是我在XML缺少Address1時收到的事件

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

但是, NODEOBJECT都是null,我無法進一步研究導致異常的原因,除非我解析我原先問的異常。

您可以為此利用JAXB的ValidationEventHandler 然后可以在MarshallerUnmarshaller實例上設置實現:

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

}

欲獲得更多信息

以下可能有用(我還沒編碼)。 您可以在XML輸入上創建StAX XMLStreamReader。 然后使用Unmarshaller解析它,並在其上設置Schema以啟用驗證。 如果發生錯誤,則解組將停止。 然后,您可以檢查XMLStreamReader當前所處的事件,以查看錯誤發生的位置。

對於您通過JAXB提出的要求,沒有完善的解決方案。 JAXB提供了對源xml進行驗證的支持,該模式依賴於 - true或false。 概念是如果xml無效,則不應繼續進行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM