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
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."
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);
}
}
});