当使用javax.xml.validation.Validator类对XSD架构验证xml时,将显示以下类型的错误消息 .

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'.

有没有办法显示用户友好的消息比上面的详细消息?

例如,在下面的xml中

如果未传递Firstname标记,则错误应为“Employee元素中需要Firstname”而不是“cvc-complex-type.2.4.a:从元素'Lastname'开始发现无效内容 . ''之一是期待 . ”如果输入phonenumber为'12345x67890',那么错误应该是“Employee元素中Phonenumber的值无效”而不是“cvc-pattern-valid:值'12345x67890'对于模式'[0-9] {而言不是方面有效的10}'代表'PhoneType' . “

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

以下是我用于根据模式验证xml的java代码

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

解决方案我用过 -

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