DOCTYPE 解決と ASP.Net に関する問題
質問
で 前の質問 DTD を使用して定義された一連の XML 入力をインターフェイスで使用するサードパーティ DLL を使用した作業について説明しました。ここまではすべて順調に進んでいますが、生成された入力値のドキュメント タイプ宣言を解決する際に、依然として厄介な問題が発生しています。
私が理解できないのは、参照される DTD ファイルをどこで探すかを決定する決め手は何なのかということです。次のような宣言があるとします。
<!DOCTYPE ElementName SYSTEM "ElementName.dtd">
私の最初の考えは、アプリケーションの現在の実行パスが、パーサーが DTD を探す場所であるということでした。ただし、使用しようとすると、 XML コントロール ASP.Net で発生するエラーに困惑しています...
ファイル 'C: Program Files Microsoft Visual Studio 9.0 Common7 IDE ElementName.dtd'を見つけることができませんでした
なぜそこで DTD を探すのでしょうか?
この件に関して私を助けてくれる XML の専門家はいますか。この DLL から返される XML を実際には制御できないので、どうすればよいでしょうか。DTD をオペレーティング システムに「登録」する方法はありますか?GACみたいな?
解決
残念ながら、XML を生成したライブラリは、dtd に対して完全修飾 URL ではなく相対 URL を使用していました。そのため、XmlControl の XmlDocument は Xmlリゾルバー クラスを使用して、相対パスを完全修飾パスに変換します。デフォルトでは、 XmlUrlリゾルバー (これは具体的な XmlResolver です)。これにより、dtd の場所を、Xml ドキュメントに対して相対的であると思われる場所にマップしようとします。問題は、XmlDocument がどこにあるのかということです。おそらく、何も相対的ではないメモリ内にあり、XmlUrlResolver は代わりにプロセスの場所を使用しています。あなたの場合は、「c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe」にある Visual Studio です。
それで、何ができるでしょうか?XmlUrlResolver を継承し、ResolveUri メソッドをオーバーライドして適切な処理を行う独自の XmlResolver を作成する必要があると思います。それが完了したら、次のことを行う必要があります。
- XmlReaderSettings クラスを作成し、作成したクラスに XmlReolver プロパティを設定します。
- XmlReader.Create() を使用して XmlReader を作成し、ドキュメントと XmlSettings オブジェクトを渡します。
- XmlDocument を作成し、Load を呼び出して XmlReader に渡します。
- XmlControl の XmlDocument プロパティを XmlDocument に設定します。
率直に言って、それはすべて少し面倒なので、私なら XML に処理する前に string.Replace を使用してドキュメントから DTD 宣言を削除します。
本当に勇気がある場合は、XmlResolver を直接継承するリゾルバーを作成できます。それが完了したら、 GetEntity メソッドを使用すると、どこからでも dtd ドキュメントを取得できます。以前、リソース ファイルとして埋め込まれたファイルから dtds を取得するものを書きましたが、残念ながら、そのコードはもうありません :-(
他のヒント
、あなたは完全にDTDを無視するようにXmlTextReaderクラス(またはXmlDocumentオブジェクト)にnullにXmlResolverのプロパティを設定することができます。