4

when an xml is validated against a XSD schema using javax.xml.validation.Validator class following type of error messages are displayed.

cvc-complex-type.2.4.a: Invalid content was found starting with element 'LastName'. One of '{FirstName}' is expected.

cvc-pattern-valid: Value '12345x67890' is not facet-valid with respect to pattern '[0-9]{10}' for type 'PhoneType'.

Is there any way to display user friendly messages than verbose message like above?

For example in the below xml

  1. if Firstname tag is not passed then error should be "Firstname is required in Employee element" isntead of "cvc-complex-type.2.4.a: Invalid content was found starting with element 'Lastname'. One of '{Firstname}' is expected."

  2. If phonenumber is entered as '12345x67890' then error should be "Invalid value for Phonenumber in Employee element" instead of "cvc-pattern-valid: Value '12345x67890' is not facet-valid with respect to pattern '[0-9]{10}' for type 'PhoneType'."

<Employee>
<Firstname></Firstname>
<Lastname></Lastname>
<PhoneNumber></PhoneNumber>
<Salary></Salary>
</Employee>

Following is the java code I used to validate xml against schema

    String schemaLang = "http://www.w3.org/2001/XMLSchema";
    XMLStreamReader reader = null;
    try {
        Validator validator =
            SchemaFactory.newInstance(schemaLang).newSchema(new StreamSource(xmlschemastream)).newValidator();
        reader =
            XMLInputFactory.newFactory().createXMLStreamReader(new StreamSource(new StringReader(xmlString.trim())));
        validator.setErrorHandler(new XsdErrorHandler(reader));
        validator.validate(new StAXSource(reader));
    } catch (Exception e) {
        System.out.println(e.getMessage());
    } 

XsdErrorHandler.java

public class XsdErrorHandler implements ErrorHandler {

    private XMLStreamReader reader;

    public XsdErrorHandler(XMLStreamReader reader) {
        this.reader = reader; }

    @Override
    public void error(SAXParseException e) throws SAXException {
          throw new SAXException(reader.getLocalName());}

    @Override
    public void fatalError(SAXParseException e) throws SAXException {
        throw new SAXException(reader.getLocalName());}

    @Override
    public void warning(SAXParseException sAXParseException) throws SAXException {}
}

Solution I used-

final List<String> exceptions = new LinkedList<>();     
validator.setErrorHandler(new ErrorHandler() {
                    @Override
                    public void warning(SAXParseException exception) throws SAXException {
                        exceptions.add(exception.getMessage());
                    }

                    @Override
                    public void fatalError(SAXParseException exception) throws SAXException {
                        exceptions.add(exception.getMessage());
                    }

                    @Override
                    public void error(SAXParseException exception) throws SAXException {

                        String message = exception.getMessage();
                        if (message.contains("cvc-type.3.1.3") || message.contains("cvc-complex-type.2.4") ||
                            message.contains("cvc-elt.1")) {
                            String[] errors = message.split(":");
                            errors[0] = "";
                            String required = "";
                            for (int i = 0; i < errors.length; i++) {
                                required = required + errors[i];
                            }
                            exceptions.add(required);
                        }
                    }
                });
springenthusiast
  • 403
  • 1
  • 8
  • 30
  • javax.xml.validation.Validator is an interface, not a class, so the answer depends on which implementation you are using. I can tell you how to go some way to achieving this requirement with the Saxon implementation of javax.xml.validation.Validator, but I won't do that unless you ask for it. – Michael Kay Jan 31 '17 at 12:02
  • I ma using default implementation provided by JRE not any third party implementation. – springenthusiast Feb 01 '17 at 06:46
  • @springbatcher were you able to figure out the solution for user friendly error message for xsd validation message? I have the same problem too, please let me know if you have a solution – OTUser Dec 07 '17 at 18:31
  • @RanPaul there's no direct solution available. I wrote my own custom message formatter based on String operation to format messages and display the same. – springenthusiast Dec 08 '17 at 05:27
  • @springbatcher could you please provide me ur message formatter, I'll customize it for my use case – OTUser Dec 08 '17 at 05:56
  • Updated question with solution used, it captures necessary messages into a list and then process each String messages based on few key words by using a property file which maintains keys and expected message incase of that keyword found in XSD validation message. – springenthusiast Dec 08 '17 at 06:54

0 Answers0