2012-10-26 10 views
5

したがって、アプリケーションはWebサービスから取得したXML文書(具体的にはPubMed)を解析します。それらの文書はDTD(an example)を宣言します。デフォルトでは、私の素朴な期待に反して、XML文書を解析する前に、私たちが使っているXMLライブラリ(JDom2、私が信じているXercesに基づいています)がそのDTDをダウンロードします。ダウンロードは、インターネット上の指定されたアドレスへのHTTPリクエストを作成します。ここで他の記事を読んでから、DTDをダウンロードせずにXML文書を解析する標準的な方法

、DTDを読むこと、それは文書で&foo;ビットを解析するために必要な実体宣言が含まれていてもよいことを考える必要があるとその私の理解(ところで、これは右、XMLの標準で狂気のですか?)

私はDTDをローカルに持っていることを指定するこの方法で、簡単で標準的な、誰もが何をしているのかが分かっているはずです。しかし、私が見ているのは、XMLカタログ(黒い魔法)を設定すること、またはカスタムのEntityResolver(私のお尻の痛み)を作成することです。

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

変更されないファイルをフェッチするためにWebリクエストを何度も繰り返さない、よく知られたライブラリを使用してXMLアプリケーションを作成するにはどうすればよいですか?

PS: この問題は、PubMedが今日の接続問題を抱えていて、XMLパーサがDTDを取得できなかったときにユニットテスト(実際のクエリに基づいて疑似文書を使用する)が失敗したことを発見しました。

PPS: 私は、W3C has issues with thisが実際にこのような悪用を求めている標準を伝播しているのは本当に面白いと思います。

+0

「あなたは自分で仕事をしなければなりません」以外の回答が得られることを願っています。私はいつもカスタムのEntityResolverを使っています。私はそれが脆弱であるとは思わなかった---まさに---しかし、単純なことをするのはたくさんのコードです。 –

答えて

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参照を置き換えて、おそらく使用される任意のエンティティ参照を挿入します。

関連する問題