Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

so right now when I validate the XML file using an XML schema, I am only able to know whether it fail or pass, and if I want to know why it fail, I need to look at the error message like

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

In the above example, it fail because I am missing tag Address1. My question is When the validation fail, can I know which tag causing the failure? This is because I need to handle these failure differently for each important missing-tag. Right now my thought is

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

However, I do not think writing logic inside catch clause is correct. Any advice?

EDIT

I followed Balaise idea, and below is the event I received when the XML missing an 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

However, both NODE and OBJECT are null, I cannot further investigate on what causing the exception unless I parse the exception which is what I asked originally.

like image 578
Thang Pham Avatar asked Dec 12 '11 14:12

Thang Pham


People also ask

How do I know if my XML schema is valid?

All you have to do is just paste the XML and click on “Check XSD validity” button. In XML Schema Definition (XSD), we can verify: Checking the schema in its value. The same name field by checking its data type.

Can we validate XML documents against a schema?

You can validate your XML documents against XML schemas only; validation against DTDs is not supported. However, although you cannot validate against DTDs, you can insert documents that contain a DOCTYPE or that refer to DTDs.

How does XML schema validation work?

XML validation is a process done to check for a syntax error in an XML document to ensure that the document is well-written with the standard rules using either DTD or schema. A complete XML file is considered to be valid XML document unless it has correct syntax and constraints defined in it.


1 Answers

You can leverage JAXB's ValidationEventHandler for this. An implementation can then be set on instances of Marshaller and 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;
    }

}

For More Information

  • http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html
  • http://bdoughan.blogspot.com/2010/11/validate-jaxb-object-model-with-xml.html
like image 165
bdoughan Avatar answered Sep 21 '22 09:09

bdoughan