有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JAXB:当使用XML模式(.xsd)验证XML文件时,如果验证失败,我能知道是哪个XML标记导致了它吗?

所以现在,当我使用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缺少地址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

然而,NODEOBJECT都是空的,我无法进一步调查导致异常的原因,除非我分析我最初询问的异常


共 (3) 个答案

  1. # 1 楼答案

    以下内容可能有用(我还没有编写代码)。您可以在XML输入上创建一个StAX XMLStreamReader。然后使用一个已设置模式的解组器从中解组,以启用验证。如果发生错误,解组将停止。然后可以检查XMLStreamReader当前处于什么事件,以查看错误发生的位置

  2. # 2 楼答案

    您可以利用JAXB的^{}实现这一点。然后可以在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;
        }
    
    }
    

    了解更多信息

  3. # 3 楼答案

    对于您通过JAXB提出的问题,没有格式良好的解决方案。JAXB提供了对验证源xml是否符合模式的支持,该模式为true或false。其概念是,如果xml无效,则不应继续