2

だから私は大量のXMLファイルを持っています。何年もの間、それらを書いている人が手作業で行っていたため、エラーが自然に発生していたため、問題が発生していました。それらを検証し、これらの XML ファイルを使用しようとしたときに何が問題なのかについてフィードバックを提供する時期が来ました。

SAX パーサーを使用して、エラーのリストを取得しています。

以下は私のコードです

  BookValidationErrorHandler errorHandler = new BookValidationErrorHandler();

        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setValidating(true);
        factory.setNamespaceAware(true);

        SchemaFactory schemaFactory = 
            SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");

        factory.setSchema(schemaFactory.newSchema(
            new Source[] {new StreamSource("test.xsd")}));


        javax.xml.parsers.SAXParser parser = factory.newSAXParser();
        org.xml.sax.XMLReader reader = parser.getXMLReader();

        reader.setErrorHandler(errorHandler);
        reader.parse(new InputSource("bad.xml"));

最初の 2 つのエラーは常に次のとおりです。

行番号: 2: ドキュメントが無効です: 文法が見つかりません。行番号: 2: ドキュメント ルート要素「credits」は、DOCTYPE ルート「null」と一致する必要があります。

チェックが必要なこれらの何千もの XML ファイルを編集することはできません。

これを防ぐためにソースの前に簡単に追加できるものはありますか? これらの DTD 関連のエラーを無視するようにパーサーに指示する方法はありますか? 文法が何を意味するのかさえわかりません。2つ目の意味はなんとなくわかります。

4

3 に答える 3

8

設定setValidating(true)は DTD 検証を要求し、DTD が存在しない場合は失敗します。DTD 検証ではなく、スキーマ検証のみが必要な場合は、 を使用しますsetValidating(false)のJavadocsetValidating()から:

setValidating(boolean)DTD の代わりに W3C XML Schema や RELAX NG などの最新のスキーマ言語を使用するには、メソッドを falseのままにしてパーサーを非検証パーサーに構成し、setSchema(Schema)メソッドを使用してスキーマをパーサーに関連付けます。

于 2011-03-04T08:59:02.130 に答える
0

これらのデイズでも同じ問題がありました。私はこのスレッドが解決策を探しているのを見つけました。私の解決策は、EntityResolverを使用することでした。スキーマを設定するだけでは不十分なようです...少なくとも私にとってはそうではありません。これはEntityResolverの例です。

public class CustomResolver implements EntityResolver {
    @Override
    public InputSource resolveEntity(String publicId, String systemId) 
            throws SAXException, IOException {

        if (systemId.equals("http://namespace1.example.com/ex1")) {
            return new InputSource("xsd_for_namespace1_path"));
        } else if (systemId.equals("http://namespace2.example.com/ex2")) {
            return new InputSource("xsd_for_namespace2_path"));
        } else if (systemId.equals("http://namespace3.example.com/ex3")) {
            return new InputSource("xsd_for_namespace3_path")); 
        }

        return null;
    }
}

setValidating()プロパティも無効にします。これは私のパーサー構成です:

SAXParserFactory saxpf = SAXParserFactory.newInstance();
saxpf.setNamespaceAware(true);
saxpf.setSchema(getSchema());
saxpf.setValidating(false);
SAXParser saxParser = saxpf.newSAXParser();
saxParser.getParser().setEntityResolver(new XSDResolver());

getSchema()メソッドは、コードで行うのと同じようにスキーマをインスタンス化しますが、より多くのソースを使用します。

同じエラーを見つけた人に役立つことを願っています。

于 2011-04-20T08:22:55.287 に答える
0

JAXP 準拠のパーサーを使用していて、Oracle のドキュメントに従って正しく構成している場合は、引き続き検証パーサーを使用でき、パーサーにスキーマを事前設定する必要はありません。

SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(true);
SAXParser saxParser = spf.newSAXParser();
// Important step next:  Tell the parser which XML schema-definition language to expect:
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
// Now when we parse a file without a DTD, we no longer get an error 
// (as long as an XSD schema is defined in the file):
saxParser.parse(source, handler);
于 2015-01-21T17:24:09.653 に答える