この日記は私的なものであり所属会社の見解とは無関係です。 GitHub: takahashikzn

SAXパーサーでXMLのwell-formednessを検証する

いま、XMLApache Digesterでパースするコードを書いているのですが、
(それにしても、DigesterのAPIはホントにわかりづらいなぁ…メソッド名が直感的じゃないというか)


not well-formedなXMLを読ませようとすると、

org.xml.sax.SAXParseException: The element type "data" must be terminated by the matching end-tag "</data>".
	at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
	at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
	at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
	at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
	at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
	at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
	at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
	at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
	at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
	at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
	at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
	at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
	at org.apache.commons.digester.Digester.parse(Digester.java:1785)
        ...

と怒られます。まあ当たり前だな、と思っていたのですが、ここでふと疑問が。


SAXって、not well-formedなドキュメントを読ませると、必ずエラーを返してくれるのでしょうか?
つまり、SAXパーサーはwell-formednessの検証をしてくれるのか?ということです。


少なくともjavadocを見る限りでは、「not well-formedなドキュメントを読ませると、絶対にエラーにするよ」
と明言している箇所は見当たらず。

ソースを読む

うーむ。めんどくさいけどXercesのソースを読んでみるか。


………見つけた。

org.apache.xerces.impl.XMLDocumentFragmentScannerImpl#scanEndElement
で閉じタグのチェックをしていました。

    protected int scanEndElement() throws IOException, XNIException {

        ...

        //REVISIT: if the string is not the same as expected.. we need to do better error handling..
        //We can skip this for now... In any case if the string doesn't match -- document is not well formed.
        if (!fEntityScanner.skipString(fElementQName.rawname)) {
            reportFatalError("ETagRequired", new Object[]{fElementQName.rawname});
        }

        ...

    } // scanEndElement():int

XMLDocumentFragmentScannerImplでは、このほかにも各種チェックを行っている模様です。


事実上の標準であるXerces以外を使うことはまずありえません。今回のプロジェクトに限ったことではなく。

なのでSAXでもwell-formedであることの検証はしているのだ、と考えてもよさそうです。