XML文書は通常、外部エンティティを参照します。例えば、文書型定義の公開IDやシステムIDなどです。これらの外部関係はURI(通常はURL)を使用して表現されます。
しかし、絶対URLはネットワークが到達可能な場合にのみ機能します。リモートリソースに依存すると、XML処理は計画的および非計画的なネットワークダウンタイムの影響を受けやすくなります。
相対URLは、最初に作成されたコンテキスト内でのみ有効です。たとえば、「../../xml/dtd/docbookx.xml」というURLは、通常、非常に限られた状況でのみ有効です。
これらの問題を回避する一つの方法は、エンティティリゾルバ( SAXの標準機能)またはURIリゾルバ(JAXPの標準機能)を使用することです。リゾルバは、要求されたリソースのURIを調べ、それらの要求を満たす最適な方法を判断できます。XMLカタログは、外部エンティティ参照とローカルにキャッシュされた同等のリソースとのマッピングを記述したドキュメントです。
次の簡単なカタログは、例えばXHTMLページ検証ツールにローカルキャッシュされたDTDを提供する方法を示しています。
<?xml version="1.0"?> <!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"><catalog xmlns= "urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer= "public" ><public publicId= "-//W3C//DTD XHTML 1.0 Strict//EN" uri= "dtd/xhtml1/xhtml1-strict.dtd" /><public publicId= "-//W3C//DTD XHTML 1.0 Transitional//EN" uri= "dtd/xhtml1/xhtml1-transitional.dtd" /><public publicId= "-//W3C//DTD XHTML 1.1//EN" uri= "dtd/xhtml11/xhtml11-flat.dtd" /></catalog>-//W3C//DTD XHTML 1.0 Strict//ENこのカタログにより、ローカルURIへの解決が可能になりますdtd/xhtml1/xhtml1-strict.dtd。同様に、他の2つの公開IDについてもローカルURIを提供します。
上記のドキュメントにはDOCTYPE宣言が含まれています。そのため、http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtdカタログリゾルバが完全に機能する前に、パーサーがDOCTYPEのシステムID URL(例:)にアクセスしようとする可能性があり、これはおそらく望ましくありません。これを防ぐには、DOCTYPE宣言を削除してください。
次の例はこれを示し、また、宣言の代替として同等の宣言も示しています。<system/><public/>
<?xml version="1.0"?> <catalog xmlns= "urn:oasis:names:tc:entity:xmlns:xml:catalog" ><system systemId= "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" uri= "dtd/xhtml1/xhtml1-strict.dtd" /><system systemId= "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" uri= "dtd/xhtml1/xhtml1-transitional.dtd" /><system systemId= "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" uri= "dtd/xhtml11/xhtml11-flat.dtd" /></catalog>カタログリゾルバは、さまざまなプログラミング言語で利用可能です。次の例は、JavaでSAXパーサーを作成し、入力ソースを解析する方法を示しています。このパーサーorg.apache.xml.resolver.tools.CatalogResolverでは、外部エンティティをローカルにキャッシュされたインスタンスに解決するために使用されます。このリゾルバはApache Xercesに由来しますが、現在はSun Javaランタイムに含まれています。
ファクトリを使用して、標準的な方法でを作成する必要がありますSAXParser。XMLリーダーのエンティティリゾルバーは、デフォルトまたはカスタムメイドのものに設定する必要があります。
final SAXParser saxParser = SAXParserFactory.newInstance (). newSAXParser ( ) ; final XMLReader reader = saxParser.getXMLReader ( ) ;final ContentHandler handler = ...; final InputSource input = ...;reader.setEntityResolver ( new CatalogResolver ( ) ) ; reader.setContentHandler ( handler ) ; reader.parse ( input ) ;SAXパーサーではなくparse、リーダーのメソッドを呼び出すことが重要です。