2

ValidatorJavaのXML (Apache Xerces実装を使用していると思います)を使用しているときに、非常に奇妙な動作のように見えることに遭遇しました。

一部のXMLドキュメントをXSDに対して検証しようとしていますが、ドキュメントが無効になる原因となるものをすべてログに記録したいと思います。自分で実装ErrorHandlerすればこれができると思いました。これにより、XMLドキュメントが誤って検証されることにすぐに気付きました(つまり、無効なXMLがXSDに対して有効であると識別されていました)。

いくつかのテストを行ったところ、以下に示すように、単にValidator'sを何かに設定すると、この動作が発生することがわかりました。ErrorHandler

validator.validate(invalidXmlSource); // XML correctly identified as INVALID

validator.setErrorHandler(new DefaultHandler());
validator.validate(invalidXmlSource); // XML incorrectly identified as VALID

指定されていない場合のValidator用途DefaultHandlerだと思いますので、なぜ振る舞いが変わっているのかわかりません。

ここで何が起こっているのですか?

編集

public void validate(File dir, String xsdPath) {
    File schemaFile = new File(xsdPath);
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = schemaFactory.newSchema(schemaFile);
    Validator validator = schema.newValidator();
    //validator.setErrorHandler(new DefaultHandler()); <-- this line causes incorrect validation
    for (File xmlFile: dir.listFiles()) {
        try {
            validator.validate(new StreamSource(xmlFile));
            System.out.println("File '" + xmlFile.getName() + "' is valid.");
        } catch (SAXException e) {
            System.out.println("File '" + xmlFile.getName() + "' is NOT valid.");
            System.out.println("Reason: " + e.getLocalizedMessage());
        } catch (IOException e) {
            e.printStackTrace();
        }       
    }
}
4

1 に答える 1

6

DefaultHandlererrorとのために何もしませんwarning。ただし、の例外がスローされfatalErrorます。Validatorとのドキュメントの間に、DefaultHandler良くも悪くも、あなたが求めていたものを正確に得ていることがわかります。:)

編集:おそらくValidatorドキュメントで注意すべき主なことは、デフォルトの(null)エラーハンドラーがerror...の例外をスローすることです。

Edit2:これがあなたが望むことをするために可能なエラーハンドラーの概要です:

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;

public class LoggingErrorHandler implements ErrorHandler {

    private boolean isValid = true;

    public boolean isValid() {
        return this.isValid;
    }

    @Override
    public void warning(SAXParseException exc) {
        // log info
        // valid or not?
    }

    @Override
    public void error(SAXParseException exc) {
        // log info
        this.isValid = false;
    }

    @Override
    public void fatalError(SAXParseException exc) throws SAXParseException {
        // log info
        this.isValid = false;
        throw exc;
    }
}

そしてそれはそのように使うことができます:

LoggingErrorHandler errorHandler = new LoggingErrorHandler();
validator.setErrorHandler(errorHandler);
validator.validate(invalidXmlSource);
if (!errorHandler.isValid()) {
    //...
}
于 2012-09-11T20:22:15.170 に答える