5

したがって、このアプリケーションは Web サービス (具体的にはPubMed ) から取得した XML ドキュメントを解析します。これらのドキュメントでは、DTD を宣言しています ()。デフォルトでは、私の単純な予想に反して、私たちが使用する XML ライブラリ (JDom2、Xerces 上に構築されていると思われます) は、XML ドキュメントを解析する前にその DTD をダウンロードします。ダウンロード。指定されたアドレスにインターネット経由で HTTP リクエストを送信します。

ここで他の投稿を読んだことから、 &foo; を解析するために必要なエンティティ宣言が含まれている可能性があるため、DTD を読むことが必要であるという私の理解 ドキュメント内のビット(ところで、これはXML標準の狂気ですよね?)

私は、DTD をローカルに持っていることを指定する簡単で標準的な方法が必要だと考えました。しかし、私が目にするのは、XML カタログのセットアップ (黒魔術) やカスタム EntityResolver の作成 (お尻の痛み) についての言及だけです。

私が遭遇する他の問題については、Spring またはその他の Java ライブラリで、多くのボイラープレートなしでそれらを克服する標準的な方法を見つけました。ただし、これについては、他のすべての開発者が遭遇しなければならない何かを達成するために、比較的ずさんで脆弱なコードを書いているように感じます。

よく知られたライブラリを使用して、決して変更されないファイルを取得するために何度も何度も Web 要求を行わない XML アプリケーションを作成するにはどうすればよいでしょうか?

PS: 私がこの問題を発見したのは、PubMed で今日の初めに接続の問題が発生し、XML パーサーが DTD を取得できなかったときに (実際のクエリに基づいてモックアップされたドキュメントを使用する) 単体テストが失敗していたためです。

PPS: W3C が、実際にこの種の乱用を要求する標準を広めたのに、W3Cがこれに問題を抱えているのは本当に面白いと思います。

4

1 に答える 1

2

別のソースから DTD をロードするために私が考えることができる最善の方法は、EntityResolver を使用することです。DOM4j 用の EntityResolver を使用してローカル xml リソースをロードし、ファイルを jar 内に配置して、次のコードで簡単にアクセスできるようにします。

new org.xml.sax.EntityResolver() 
{
    @Override
    public InputSource resolveEntity(String publicId, String systemId)
    {
        if (systemId != null && systemId.equals("http://something.com/xml.dtd"))
            return new InputSource(getClass().getResourceAsStream("../xml/local.dtd"));;
    }
};

それが「標準的な」方法だと思います。

文字列を介して xml ドキュメントを変更する別の方法として、dtd 参照を置き換え、使用されるエンティティ参照を挿入します。

于 2012-12-15T12:09:55.050 に答える