4 XMLカタログAPI
XMLカタログAPIを使用してローカルXMLカタログを実装します。
Java SE 9では、新しいXMLカタログAPIが導入され、Organization for the Advancement of Structured Information Standards (OASIS) XMLカタログ、OASIS標準V1.1、2005年10月7日がサポートされるようになりました。 コア・ライブラリ・ガイドのこの章では、API、Java XMLプロセッサによるサポート、および使用パターンについて説明します。
XMLカタログAPIは、ローカル・カタログを実装するための単純なAPIであり、JDK XMLプロセッサによるサポートによってプロセッサや環境全体の構成が容易になり、その機能を活用することができます。
カタログ作成の詳細の学習
カタログ作成について学習するには、XMLカタログ、OASIS標準V1.1、2005年10月7日を参照してください。一部のLinuxディストリビューションの/etc/xml/catalog
ディレクトリの下にあるXMLカタログもまた、ローカル・カタログを作成するための参考になります。
XMLカタログAPIの目的
XMLカタログAPIとJava XMLプロセッサには、外部リソースを管理するための、開発者およびシステム管理者向けのオプションが用意されています。
XMLカタログAPIは、外部リソースが原因で発生する問題に対処するために設計された標準の、OASIS XMLカタログv1.1の実装を提供します。
外部リソースが原因で発生する問題
XML、XSDおよびXSLのドキュメントには、Java XMLプロセッサがドキュメントを処理するために取得する必要がある、外部リソースへの参照が含まれている可能性があります。外部リソースによってアプリケーションまたはシステムに問題が発生する場合があります。カタログAPIとJava XMLプロセッサには、これらの外部リソースを管理するための、開発者およびシステム管理者向けのオプションが用意されています。
外部リソースによって、アプリケーションまたはシステムの次の領域に問題が発生する場合があります:
-
可用性: リソースがリモートの場合、XMLプロセッサはリソースをホストするリモート・サーバーに接続できる必要があります。接続性が問題となることはまれですが、アプリケーションの安定性に影響する要因になります。接続が多すぎると、リソースを保持しているサーバーに障害が発生し、アプリケーションに影響を及ぼす可能性があります。XMLカタログAPIを使用してこの問題を解決する例は、「XMLプロセッサでのカタログの使用」を参照してください。
-
パフォーマンス。接続性が問題になることはほとんどありませんが、リモート・フェッチによってアプリケーションのパフォーマンスに問題が生じることがあります。さらに、同じシステム上に同じリソースの解決を試行するアプリケーションが複数存在する場合があり、これによってシステム・リソースに無駄が生じます。
-
セキュリティ: リモート接続を許可すると、アプリケーションで信頼されないXMLソースが処理された場合にセキュリティ・リスクが発生します。
-
管理性: システムで多数のXMLドキュメントを処理する場合、外部参照ドキュメントが(ローカルかリモートかに関係なく)保守上の問題になる可能性があります。
外部リソースが原因で発生する問題にXMLカタログAPIで対応する方法
アプリケーション開発者は、アプリケーションのすべての外部参照のローカル・カタログを作成し、カタログAPIを使用して参照をアプリケーション用に解決します。これによって、リモート接続が回避されるだけでなく、これらのリソースの管理が容易になります。
システム管理者は、システムのローカル・カタログを確立し、そのカタログを使用するようにJava VMを構成できます。次に、システム上のすべてのアプリケーションがアプリケーションのコードを変更することなく(Java SE 9と互換性があることを想定)、同じカタログを共有します。カタログを確立するために、一部のLinuxディストリビューションに含まれるカタログなどの既存のカタログを使用できます。
XMLカタログAPIのインタフェース
XMLカタログAPIにアクセスするは、XMLカタログAPIのインタフェースを使用します。
XMLカタログAPIのインタフェース
XMLカタログAPIでは、次のインタフェースが定義されています。
-
Catalog
インタフェースは、XMLカタログ、OASIS標準V1.1 (2005年10月7日)で定義されているとおり、エンティティ・カタログを表します。Catalog
オブジェクトは不変です。Catalog
オブジェクトを作成したら、これを使用してsystem
、public
、またはuri
エントリ内の一致を探します。カスタム・リゾルバを実装すると、カタログを使用してローカル・リソースを検索するのが便利であることがわかります。 -
CatalogFeatures
クラスには、javax.xml.catalog.files
、javax.xml.catalog.defer
、javax.xml.catalog.prefer
、およびjavax.xml.catalog.resolve
などの、カタログAPIがサポートする機能とプロパティが保持されています。 -
CatalogManager
クラスは、XMLカタログおよびカタログ・リゾルバの作成を管理します。 -
CatalogResolver
インタフェースは、スキーマ検証で使用するSAXEntityResolver
、StAXXMLResolver
、DOM LSLSResourceResolver
、および変換URIResolver
を実装するカタログ・リゾルバです。インタフェースではカタログを使用して外部参照が解決されます。
CatalogFeaturesクラスの詳細
カタログ機能はCatalogFeaturesクラスにまとめて定義されています。機能はAPIレベルとシステム・レベルで定義されており、API、システム・プロパティおよびJAXPプロパティを使用して設定できます。APIを使用して機能を設定するには、CatalogFeaturesクラスを使用します。
次のコードでは、javax.xml.catalog.resolveがcontinue
に設定されるため、CatalogResolver
によって一致が見つからなくても処理は続行します:
CatalogFeatures f = CatalogFeatures.builder().with(Feature.RESOLVE, "continue").build();
このcontinue
機能をシステム全体に設定するには、JavaコマンドラインまたはSystem.setPropertyメソッドを使用します:
System.setProperty(Feature.RESOLVE.getPropertyName(), "continue");
このcontinue
機能をJVMインスタンス全体に設定するには、jaxp.properties
ファイルに次の行を入力します:
javax.xml.catalog.resolve = "continue"
jaxp.properties
ファイルは通常、$JAVA_HOME/conf
ディレクトリにあります。
resolve
プロパティと、prefer
およびdefer
の各プロパティは、カタログの属性またはカタログ・ファイルのグループ・エンティティとして設定できます。たとえば、次のカタログでは、resolve
属性が値continue
で設定されています。属性は、次のようにgroup
エントリでも設定できます。
<?xml version="1.0" encoding="UTF-8"?>
<catalog
xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"
resolve="continue"
xml:base="http://local/base/dtd/">
<group resolve="continue">
<system
systemId="http://remote/dtd/alice/docAlice.dtd"
uri="http://local/dtd/docAliceSys.dtd"/>
</group>
</catalog>
より狭い範囲に設定されたプロパティは広い範囲に設定された属性をオーバーライドします。そのため、APIを使用して設定されたプロパティが常に優先されます。
XMLカタログAPIの使用
XMLカタログ標準の様々なエントリ・タイプを使用して、XMLソース・ドキュメントのDTD、エンティティおよび代替URI参照を解決します。
XMLカタログ標準では、数多くのエントリ・タイプが定義されています。そのうち、system
、rewriteSystem
およびsystemSuffix
の各エントリを含むシステム・エントリはXMLソース・ドキュメントのDTDおよびエンティティ参照を解決するために使用され、uri
エントリは代替URI参照用です。
システム参照
CatalogResolver
オブジェクトを使用してローカル・リソースを検索します。
ローカル・リソースの検索
次の例では、CatalogResolver
オブジェクトを使用してローカル・リソースを検索する方法を示します。
次のXMLファイルを考えます:
<?xml version="1.0"?>
<!DOCTYPE catalogtest PUBLIC "-//OPENJDK//XML CATALOG DTD//1.0"
"http://openjdk.java.net/xml/catalog/dtd/example.dtd">
<catalogtest>
Test &example; entry
</catalogtest>
example.dtd
ファイルは、エンティティexample
を定義します:
<!ENTITY example "system">
ただし、XMLファイルにexample.dtd
ファイルへのURIが存在している必要はありません。一意の識別子を指定するのは、CatalogResolver
オブジェクトでローカル・リソースを検索するのが目的です。これを行うには、catalog.xml
というカタログ・エントリ・ファイルにローカル・リソースを参照するためのsystem
エントリを作成します。
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system
systemId="http://openjdk.java.net/xml/catalog/dtd/example.dtd"
uri="example.dtd"/>
</catalog>
このカタログ・エントリ・ファイルとsystem
エントリを使用して行うことは、デフォルトのCatalogFeatures
オブジェクトを取得し、カタログ・エントリ・ファイルへのURIを設定してCatalogResolver
オブジェクトを作成するだけです:
CatalogResolver cr =
CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogUri);
catalogUri
は有効なURIである必要があります。次に例を示します。
URI.create("file:///users/auser/catalog/catalog.xml")
CatalogResolver
オブジェクトをJDK XMLリゾルバとして使用できるようになりました。次の例では、SAX EntityResolver
として使用されています。
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
XMLReader reader = factory.newSAXParser().getXMLReader();
reader.setEntityResolver(cr);
例ではシステム識別子に絶対URIが指定されていることに注意してください。これにより、リゾルバがカタログのsystem
エントリに完全に一致するsystemId
を検索することが容易になります。
XMLのsystem
識別子が相対である場合は、XMLプロセッサで指定のベースURIまたはソース・ファイルのURIを使用して絶対化する必要があるため、一致プロセスが複雑になります。その場合、システム・エントリのsystemId
が予期される絶対URIと一致する必要があります。より簡単に解決するには、次のようにsystemSuffix
エントリを使用します。
<systemSuffix systemIdSuffix="example.dtd" uri="example.dtd"/>
systemSuffix
エントリは、XMLソースのexample.dtd
で終わる任意の参照と一致し、それをuri
属性に指定されているとおりにローカルのexample.dtd
ファイルに解決します。systemId
が一意または正しい参照になるように、詳細を追加します。たとえば、systemIdSuffix
をxml/catalog/dtd/example.dtd
に設定するか、XMLソース・ファイルとsystemSuffix
エントリの両方でid
が一意に一致するように名前を変更します(例: my_example.dtd
)。
system
エントリのURIには、絶対URIまたは相対URIを指定できます。外部リソースの場所が固定されている場合は、絶対URIの方が一意性が保証されます。外部リソースがカタログ・エントリ・ファイルまたはアプリケーションに対して相対的な位置にある場合は、相対URIの方が効果的であり、アプリケーションのデプロイメントでインストール場所を意識する必要がありません。そのような相対URIは、ベースURIまたはカタログ・ファイルのURI (ベースURIが指定されていない場合)を使用して解決されます。前述の例では、example.dtd
がカタログ・ファイルと同じディレクトリに置かれていることを想定しています。
パブリック参照
system
エントリのかわりにpublic
エントリを使用して目的のリソースを検索します。
目的のリソースにsystem
エントリが一致せず、PREFER
プロパティがpublic
と一致するように指定されている場合は、public
エントリを使用してsystem
エントリと同じことを行えます。PREFER
プロパティのデフォルト設定はpublic
です。
パブリック・エントリの使用
解析済XMLファイルのDTD参照に"-//OPENJDK//XML CATALOG DTD//1.0"
のようなパブリック識別子が含まれている場合は、カタログ・エントリ・ファイルのpublic
エントリを次のように記述できます。
<public publicId="-//OPENJDK//XML CATALOG DTD//1.0" uri="example.dtd"/>
CatalogResolver
オブジェクトを作成してこのエントリ・ファイルと使用する場合、example.dtd
はpublicId
プロパティを使用して解決されます。CatalogResolver
オブジェクトの作成例は、「システム参照」を参照してください。
URI参照
uri
エントリを使用して目的のリソースを検索します。
uri
、rewriteURI
およびuriSuffix
などのURIタイプのエントリは、システム・タイプのエントリと同じように使用できます。
URIエントリの使用
XMLカタログ標準では、system
タイプのエントリにはDTD参照の解決、uri
タイプのエントリにはその他すべてのプリファレンスが指定されていますが、Java XMLカタログAPIではそのような区別がありません。これは、XMLResolver
およびLSResourceResolver
などの既存のJava XMLリゾルバの仕様ではプリファレンスを指定しないためです。uri
、rewriteURI
およびuriSuffix
などのuri
タイプのエントリは、system
タイプのエントリと同じように使用できます。uri
要素は、代替URI参照とURI参照を関連付けるために定義されます。system
参照の場合、これはsystemId
プロパティです。
そのため、system
エントリは一般的にはDTD参照に使用されますが、次の例のようにsystem
エントリをuri
エントリに置き換えることができます。
<system
systemId="http://openjdk.java.net/xml/catalog/dtd/example.dtd"
uri="example.dtd"/>
uri
エントリの例を次に示します。
<uri name="http://openjdk.java.net/xml/catalog/dtd/example.dtd" uri="example.dtd"/>
system
エントリがDTDのために使用されるのに対して、uri
エントリはXSDおよびXSLのインポートとインクルードなどのURI参照に使用されます。次の例では、XSLインポートの解決にuri
エントリが使用されています。
XMLカタログAPIのインタフェースで説明しているように、XMLカタログAPIでは、EntityResolver
、XMLResolver
、URIResolver
、LSResolver
などのJava XMLリゾルバを拡張するCatalogResolver
インタフェースが定義されています。そのため、CatalogResolver
オブジェクトは、SAX、DOM、StAX、スキーマ検証およびXSLT変換で使用できます。次のコードでは、CatalogResolver
オブジェクトがデフォルトの機能設定で作成されます。
CatalogResolver cr =
CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogUri);
コードでは次に、このCatalogResolver
オブジェクトをURIResolver
オブジェクトが予期されるTransformerFactory
クラスに登録します。
TransformerFactory factory = TransformerFactory.newInstance();
factory.setURIResolver(cr);
かわりに、コードでCatalogResolver
オブジェクトをTransformer
オブジェクトに登録することもできます。
Transformer transformer = factory.newTransformer(xslSource);
transformer.setURIResolver(cur);
XSLソース・ファイルに、xslImport.xsl
ファイルをXSLソースにインポートするためのimport
要素が含まれているとします。
<xsl:import href="pathto/xslImport.xsl"/>
import
参照をインポート・ファイルが実際にある場所に解決するには、Transformer
オブジェクトを作成する前にCatalogResolver
オブジェクトがTransformerFactory
クラスに設定されており、カタログ・エントリ・ファイルに次のようなuri
エントリが追加されている必要があります。
<uri name="pathto/xslImport.xsl" uri="xslImport.xsl"/>
システム参照における絶対URIと相対URI、およびsystemSuffix
エントリまたはuriSuffix
エントリの使用に関する検討は、uri
エントリにも当てはまります。
Java XMLプロセッサ・サポート
XMLカタログ機能を標準Java XMLプロセッサと使用します。
XMLカタログ機能は、SAXおよびDOM (javax.xml.parsers
)、StAXパーサー(javax.xml.stream
)、スキーマ検証(javax.xml.validation
)、XML変換(javax.xml.transform
)などのJava XMLプロセッサを使用してサポートされます。
これは、XMLプロセッサの外部にCatalogResolverオブジェクトを作成する必要がないことを意味します。カタログ・ファイルは、Java XMLプロセッサに直接登録するか、システム・プロパティを使用して指定するか、jaxp.propertiesファイルに指定できます。XMLプロセッサによって自動的にカタログを使用したマッピングが実行されます。
カタログ・サポートの有効化
プロセッサでのXMLカタログ機能のサポートを有効化するには、USE_CATALOG
機能がtrue
に設定されており、少なくとも1つのカタログ・エントリ・ファイルが指定されている必要があります。
USE_CATALOG
Java XMLプロセッサによって、XMLカタログ機能がUSE_CATALOG
機能の値に基づいてサポートされるかどうかが決定されます。デフォルトでは、USE_CATALOG
はすべてのJDK XMLプロセッサに対してtrue
に設定されています。Java XMLはさらにカタログ・ファイルの使用可能性を確認し、USE_CATALOG
機能がtrue
でカタログが使用可能である場合にのみ、XMLカタログAPIの使用を試行します。
USE_CATALOG
機能は、XMLカタログAPI、システム・プロパティおよびjaxp.properties
ファイルによってサポートされます。たとえば、USE_CATALOG
がtrue
に設定されており、特定のプロセッサに対するカタログ・サポートを無効化する場合は、プロセッサのsetFeature
メソッドを使用してUSE_CATALOG
機能をfalse
に設定します。次のコードでは、XMLReader
オブジェクトに対して、USE_CATALOG
機能が指定値のuseCatalog
に設定されます。
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
XMLReader reader = spf.newSAXParser().getXMLReader();
if (setUseCatalog) {
reader.setFeature(XMLConstants.USE_CATALOG, useCatalog);
}
一方、環境全体でカタログをオフにする必要がある場合は、jaxp.properties
ファイルに次の行を構成します。
javax.xml.useCatalog = false;
javax.xml.catalog.files
javax.xml.catalog.files
プロパティはXMLカタログAPIによって定義され、JDK XMLプロセッサにその他のカタログ機能とともにサポートされます。システム・プロパティまたはjaxp.properties
ファイルを使用してプロセッサにFILES
プロパティを設定するだけで、解析、検証または変換プロセスでカタログ機能を使用できます。
カタログURI
カタログ・ファイル参照は、file:///users/auser/catalog/catalog.xml
のような有効なURIである必要があります。
システムまたはカタログ・ファイルのURIエントリのURI参照は、絶対または相対で指定できます。相対の場合は、カタログ・ファイルのURIまたはベースURI(指定された場合)を使用して解決されます。
システム・エントリまたはuriエントリの使用
XMLカタログAPIを直接使用する場合(例はXMLカタログAPIのインタフェースを参照)、JDK XMLプロセッサでCatalogFeatures
クラスのネイティブ・サポートを使用すると、system
エントリとuri
エントリの両方が機能します。通常は、最初にsystem
エントリ、次にpublic
エントリが検索され、一致が見つからない場合はプロセッサによって引き続きuri
エントリが検索されます。system
エントリとuri
エントリの両方がサポートされるため、system
またはuri
のどちらのエントリを使用するかを選択する場合は、XML仕様の慣例に従うことをお薦めします。たとえば、DTDはsystemId
を使用して定義されるため、system
エントリを使用することをお薦めします。
XMLプロセッサでのカタログの使用
XMLカタログAPIを様々なJava XMLプロセッサで使用します。
XMLカタログAPIはすべてのJDK XMLプロセッサでサポートされます。次の項では、特定のタイプのプロセッサでこれを有効化する方法について説明します。
DOMでのカタログの使用
DOMでカタログを使用するには、次のコードで示すように、DocumentBuilderFactory
インスタンスにFILES
プロパティを設定します。
static final String CATALOG_FILE = CatalogFeatures.Feature.FILES.getPropertyName();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
if (catalog != null) {
dbf.setAttribute(CATALOG_FILE, catalog);
}
catalog
はカタログ・ファイルへのURIであることに注意してください。たとえば、"file:///users/auser/catalog/catalog.xml"
のようになります。
解決対象のファイルとともにカタログ・エントリ・ファイルをデプロイするのが最良の方法であり、こうすることでファイルはカタログ・ファイルに対して相対的に解決されます。たとえば、カタログ・ファイルのuri
エントリが次に示すようになっている場合、XSLImport_html.xsl
ファイルは/users/auser/catalog/XSLImport_html.xsl
にあります。
<uri name="pathto/XSLImport_html.xsl" uri="XSLImport_html.xsl"/>
SAXでのカタログの使用
SAXパーサーでカタログ機能を使用するには、カタログ・ファイルをSAXParser
インスタンスに設定します。
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setXIncludeAware(true);
SAXParser parser = spf.newSAXParser();
parser.setProperty(CATALOG_FILE, catalog);
前述のサンプル・コードの文spf.setXIncludeAware(true)
に注意してください。これが有効になっていると、XInclude
も同様にカタログを使用して解決されます。
XMLファイルXI_simple.xml
が次のようであるとします。
<simple>
<test xmlns:xinclude="http://www.w3.org/2001/XInclude">
<latin1>
<firstElement/>
<xinclude:include href="pathto/XI_text.xml" parse="text"/>
<insideChildren/>
<another>
<deeper>text</deeper>
</another>
</latin1>
<test2>
<xinclude:include href="pathto/XI_test2.xml"/>
</test2>
</test>
</simple>
さらに、別のXMLファイルXI_test2.xml
が次のようであるとします。
<?xml version="1.0"?>
<!-- comment before root -->
<!DOCTYPE red SYSTEM "pathto/XI_red.dtd">
<red xmlns:xinclude="http://www.w3.org/2001/XInclude">
<blue>
<xinclude:include href="pathto/XI_text.xml" parse="text"/>
</blue>
</red>
別のテキスト・ファイルXI_text.xml
に単純な文字列が含まれており、ファイルXI_red.dtd
が次のようであるとします。
<!ENTITY red "it is read">
これらのXMLファイルにはXInclude
要素の中にXInclude
要素が含まれており、DTDへの参照があります。これらがカタログ・ファイルCatalogSupport.xml
とともに同じフォルダ内にある場合は、これらをマップするために次のカタログ・エントリを追加します。
<uri name="pathto/XI_text.xml" uri="XI_text.xml"/>
<uri name="pathto/XI_test2.xml" uri="XI_test2.xml"/>
<system systemId="pathto/XI_red.dtd" uri="XI_red.dtd"/>
XI_simple.xml
ファイルを解析するためにparser.parse
メソッドがコールされると、指定されたカタログを使用して、XI_simple.xml
ファイルの中のXI_test2.xml
を見つけることができ、XI_test2.xml
ファイルの中のXI_text.xml
ファイルとXI_red.dtd
ファイルを見つけることができます。
StAXでのカタログの使用
StAXパーサーでカタログ機能を使用するには、XMLStreamReader
オブジェクトを作成する前に、カタログ・ファイルをXMLInputFactory
インスタンスに設定します。
XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
XMLStreamReader streamReader =
factory.createXMLStreamReader(xml, new FileInputStream(xml));
XMLソースの解析にXMLStreamReader
streamReader
オブジェクトを使用すると、ソースの外部参照はカタログに指定されているエントリに従って解決されます。
setFeature
メソッドとsetAttribute
メソッドの両方を持っているDocumentBuilderFactory
クラスとは異なり、XMLInputFactory
ではsetProperty
メソッドのみが定義されることに注意してください。XMLConstants.USE_CATALOG
を含むXMLカタログAPIはすべて、このsetProperty
メソッドを使用して設定されます。たとえば、XMLStreamReader
オブジェクトでUSE_CATALOG
を無効化するには、次のようにします。
factory.setProperty(XMLConstants.USE_CATALOG, false);
スキーマ検証でのカタログの使用
カタログを使用してスキーマ内の外部リソースを解決するには(XSD import
およびinclude
など)、SchemaFactory
オブジェクトにカタログを設定します。
SchemaFactory factory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
factory.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
Schema schema = factory.newSchema(schemaFile);
XMLSchemaスキーマ・ドキュメントには外部DTDへの参照が含まれています。
<!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "pathto/XMLSchema.dtd" [
...
]>
およびxsd
インポートも含まれています。
<xs:import
namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/pathto/xml.xsd">
<xs:annotation>
<xs:documentation>
Get access to the xml: attribute groups for xml:lang
as declared on 'schema' and 'documentation' below
</xs:documentation>
</xs:annotation>
</xs:import>
この例に従ってローカル・リソースを使用すると、W3Cサーバーへのコールが減ることによってアプリケーションのパフォーマンスが改善します。
-
SchemaFactory
オブジェクトに設定されているカタログに次のエントリを含めます。
<public publicId="-//W3C//DTD XMLSCHEMA 200102//EN" uri="XMLSchema.dtd"/>
<!-- XMLSchema.dtd refers to datatypes.dtd -->
<systemSuffix systemIdSuffix="datatypes.dtd" uri="datatypes.dtd"/>
<uri name="http://www.w3.org/2001/pathto/xml.xsd" uri="xml.xsd"/>
-
XMLSchema.dtd
、datatypes.dtd
およびxml.xsd
のソース・ファイルをダウンロードし、カタログ・ファイルとともに保存します。
前述のとおり、XMLカタログAPIでは任意のエントリ・タイプを使用できます。前述のケースでは、uri
エントリのかわりに次のいずれかを使用できます。
-
public
エントリ。import
要素のnamespace
属性がpublicId
要素として扱われるためです。
<public publicId="http://www.w3.org/XML/1998/namespace" uri="xml.xsd"/>
-
system
エントリ。
<system systemId="http://www.w3.org/2001/pathto/xml.xsd" uri="xml.xsd"/>
ノート:
XMLカタログAPIを使用したテストでは、サンプル・ファイルで使用されるURIまたはシステムIDが、インターネット上にある実際のリソース(特にW3Cサーバー)をポイントしていないことを確認してください。これによって、カタログの解決の失敗を早期に発見でき、W3Cサーバーに負荷をかけることなく、不要な接続を防ぐことができます。そのため、このトピックおよびXMLカタログAPIに関係するその他のトピックでは、すべての例のURIに恣意的な文字列"pathto"
が追加されており、URIが外部のW3Cリソースに解決されないようにしています。
カタログを使用して検証対象のXMLソースの外部リソースを解決するには: Validator
オブジェクトにカタログを設定します。
SchemaFactory schemaFactory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema();
Validator validator = schema.newValidator();
validator.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
StreamSource source = new StreamSource(new File(xml));
validator.validate(source);
変換でのカタログの使用
XSLT変換プロセスでXMLカタログAPIを使用するには、TransformerFactory
オブジェクトにカタログ・ファイルを設定します。
TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
Transformer transformer = factory.newTransformer(xslSource);
Transformer
オブジェクトを作成するためにファクトリで使用しているXSLソースに次のようなDTD、import文およびinclude文が含まれている場合、
<!DOCTYPE HTMLlat1 SYSTEM "http://openjdk.java.net/xml/catalog/dtd/XSLDTD.dtd">
<xsl:import href="pathto/XSLImport_html.xsl"/>
<xsl:include href="pathto/XSLInclude_header.xsl"/>
これらの参照を解決するために次のカタログ・エントリを使用できます。
<system
systemId="http://openjdk.java.net/xml/catalog/dtd/XSLDTD.dtd"
uri="XSLDTD.dtd"/>
<uri name="pathto/XSLImport_html.xsl" uri="XSLImport_html.xsl"/>
<uri name="pathto/XSLInclude_header.xsl" uri="XSLInclude_header.xsl"/>
リゾルバのコール順序
JDK XMLプロセッサはカタログ・リゾルバの前にカスタム・リゾルバをコールします。
カタログ・リゾルバより優先されるカスタム・リゾルバ
カタログ・ファイルが設定されているJDK XMLプロセッサでは、カタログ・リゾルバ(CatalogResolver
インタフェースで定義される)を使用して外部参照を解決できます。ただし、カスタム・リゾルバも指定されている場合は、これが常にカタログ・リゾルバより優先されます。つまり、JDK XMLは最初にカスタム・リゾルバをコールして外部リソースの解決を試行します。正常に解決された場合、プロセッサはカタログ・リゾルバをスキップして続行します。カスタム・リゾルバがないか、カスタム・リゾルバによる解決でnullが返された場合にのみ、プロセッサはカタログ・リゾルバをコールします。
カスタム・リゾルバを使用するアプリケーションでは、カスタム・リゾルバが処理できないリソースを解決するために、追加のカタログを設定します。コードを変更できない既存のアプリケーションでは、システム・プロパティを使用してカタログを設定するか、jaxp.properties
ファイルで外部参照を(この設定によってカスタム・リゾルバが処理する既存のプロセスに干渉しないことがわかっている)ローカル・リソースにリダイレクトします。
エラーの検出
問題を分離して構成の問題を検出します。
XMLカタログ標準では、プロセッサがリソースの障害からリカバリできることを必要としています。そのため、XMLカタログAPIでは、問題のあるカタログ・エントリ・ファイルはエラーが発行されることなく無視されます。これによって構成の問題を検出するのが難しくなります。
構成の問題の検出
構成の問題を検出するには、カタログを1つずつ設定し、RESOLVE
の値をstrict
に設定し、一致が見つからなかった場合はCatalogException
例外を確認することで、問題を分離します。
表4-1 RESOLVEの設定
RESOLVEの値 | CatalogResolverの動作 | 説明 |
---|---|---|
|
指定された参照に一致が見つからなかった場合は |
参照の不一致は、カタログの内容またはカタログの設定にエラーがあることを示します。 |
|
動作なし |
これは、カタログに含まれていない外部参照を解決するためにXMLプロセッサを続行する、本番環境での使用に適しています。 |
|
動作なし |
外部参照のスキップが許可されるSAXのようなプロセッサの場合、 |