この章の内容は次のとおりです。
バイナリXMLは、Oracle 11gリリース1(11.1)で導入された機能です。バイナリXMLを使用すると、XMLテキストと圧縮バイナリXMLの間でのエンコードおよびデコードが可能になります。効率を考慮して、DOMおよびSAX APIは、XMLアプリケーションが直接使用できるようにバイナリXMLの上位にあります。XMLドキュメントのフラグメントの圧縮と解凍により、インクリメンタル処理が促進されます。
この章では、XML Parser for Javaを十分に理解していると想定します。
XMLType記憶域オプションは、XML文書を新しいバイナリ形式で格納するために提供されています。この新しい記憶域オプションは、既存のCLOBオプションおよびオブジェクト・リレーショナル記憶域オプションに追加されるものです。新しいバイナリXML記憶域オプションを使用して、XMLTypeの表および列を作成することができます。バイナリ形式のXMLデータは、XMLType上で動作するすべての既存のSQL演算子および関数、およびPL/SQL APIでアクセスおよび操作することができます。
バイナリXMLは、XMLデータの簡潔なXMLスキーマ対応エンコーディングですが、XMLスキーマに基づいていないXMLデータで使用することもできます。データベース外にあるXMLデータについても(たとえばクライアント側アプリケーションで)バイナリXMLを使用することができます。バイナリXMLを使用すると、テキストからバイナリ、およびバイナリからテキストへのXML文書のエンコーディングおよびデコーディングが可能です。バイナリXMLはネイティブなデータベース・データ型を持つ解析後の永続的なXMLです。
バイナリXMLでは、非構造化記憶域より効率的なデータベースの格納、更新、索引付け、問合せ性能およびフラグメント抽出が可能です。データとメタデータは一緒に、または分けて格納することができます。
バイナリXMLプロセッサとは、バイナリXML形式をテキストに、またXMLテキストをバイナリXML形式に処理および変換するコンポーネントを説明する抽象語です。スキーマを格納するためのキャッシュも提供されます。バイナリXMLプロセッサのベース・クラスはBinXMLProcessorです。バイナリXMLプロセッサでは、ネットワーク・プロトコル・リクエストを発信または受信できます。
バイナリXML for Javaにはいくつかの使用モデルがあります。最初に用語集を示します。
次にバイナリXMLの使用方法に関する用語集を示します。
ドキュメントID: エンコード済の各XML文書は、一意のドキュメントIDにより識別されます。これは、16バイトのグローバル・ユーザーID(GUID)またはURLなどの不透明なバイト列です。
トークン表: テキストXML文書に、関連付けられたスキーマがない場合、繰返し項目の容量を最小化するためにトークン(または記号)表が使用されます。
ボキャブラリID: スキーマID、またはトークン表の名前空間URI識別です。
スキーマID: バイナリXMLプロセッサを有効範囲とするスキーマの一意の不透明なバイナリID。スキーマIDはバイナリXMLプロセッサに対して一意で、そのバイナリXMLプロセッサの有効範囲内でのみ識別可能です。スキーマIDは、スキーマが拡張された場合も不変です。スキーマIDは、インポートされたスキーマやインクルードされたスキーマなどを含むスキーマ文書セットの全体を表します。
スキーマ・バージョン: 注釈付きのスキーマにはすべて、それに関連付けられたバージョン番号があります。バージョン番号はシステム・レベルの注釈の一部として規定されます。スキーマが拡張されると(つまり、同一のスキーマの新しいバージョンがそのバイナリXMLプロセッサに登録されると)、バイナリXMLプロセッサによって増分されます。
部分妥当性: バイナリXMLのスキーマを使用するストリーム・エンコーディングは、スキーマに関する少なくとも部分妥当性を前提としています。部分妥当性には、一意のキー、キー参照、IDまたはIDREFに関する検証は含まれません。
これはバイナリXMLの最も単純な使用例です。単一のバイナリXMLプロセッサがあります。使用可能な唯一のリポジトリは、永続的でなく、バイナリXMLプロセッサが存在する間だけ使用できる、ローカルなメモリー内ボキャブラリ・キャッシュです。すべてのスキーマはあらかじめエンコーディング前にバイナリXMLプロセッサに登録される必要がありますが、XMLプロセッサがxsi:SchemaLocationタグを認識したときに自動登録させることもできます。デコーディングの場合、スキーマはボキャブラリ・キャッシュですでに使用可能です。
異なるバイナリXMLプロセッサでデコーディングが発生する場合は、ここで説明する様々なWebサービスを参照してください。
この使用例では、バイナリXMLプロセッサはJDBCを使用してデータベースに接続しています。スキーマがエンコーディングの前にデータベースで登録されていると想定します。
その実行方法の例を次に示します。
BEGIN
DBMS_XMLSCHEMA.registerSchema(
SCHEMAURL =>
'http://xmlns.oracle.com/xdb/documentation/purchaseOrder.xsd',
SCHEMADOC =>
bfilename('XMLDIR','purchaseOrder.xsd'),
CSID => nls_charset_id('AL32UTF8'),
GENTYPES => FALSE,
OPTIONS => REGISTER_BINARYXML );
END;
/
データに対して別個の接続が指定(associateDataConnection()を使用)されているのでなければ、エンコーディングでもデコーディングでも同じ接続を使用してすべてのデータとメタデータが格納および取得されるとします。
このシナリオでは複数のクライアントがあり、それぞれでバイナリXMLプロセッサが実行されています。エンコーディングするクライアントとデコーディングするクライアントは異なります。メタデータを格納するための、すべてのクライアントに接続された共有リポジトリ(データベースでなくてもかまいません)があります。これはファイル・システムでも何か他のリポジトリでもかまいません。最初のバイナリXMLプロセッサは、エンコーディングを実行する前に、スキーマがリポジトリに登録されるか、エンコーディング時にxsi:schemaLocationタグを使用してスキーマが自動的に登録されることを保証します。2番目のバイナリXMLプロセッサはデコーディングに使用され、スキーマの場所を認識しません。スキーマはリポジトリからフェッチします。
最初のバイナリXMLプロセッサがスキーマを登録し、2番目のバイナリXMLプロセッサが同一のスキーマをリポジトリに登録すると、バイナリXMLプロセッサはスキーマをコンパイルしないで、ローカルなボキャブラリ・キャッシュにある、既存のコンパイル済スキーマのvocabulary-idを戻します。
BinXMLProcessorはスレッド・セーフではないため、リポジトリにアクセスする複数のスレッドまたはクライアントは独自のセーフティ・スキームを実装する必要があります。
このシナリオでは複数のクライアントがあり、それぞれでバイナリXMLプロセッサが実行されています。エンコーディングとデコーディングが異なったクライアント上で発生する可能性があります。共有メタデータ・リポジトリはありません。エンコーダは、次のクライアントに渡されたバイナリ・データがスキーマに依存しない、つまりインライン・トークン定義を持っていることを保証する必要があります。そうするには、エンコード時にsetProperty()メソッドを使用してschemaAware = false、およびinlineTokenDefs = trueと設定します。デコーディング時にスキーマは必要ありません。
Java XMLバイナリ機能には次の3つの部分があります。
バイナリXMLエンコーディング: バイナリXMLエンコーダはXML 1.0 infosetをバイナリXMLに変換します。
BバイナリXMLデコーディング: バイナリXMLデコーダはバイナリXMLをXML infosetに変換します。
スキーマ管理、トークン管理などのバイナリXMLボキャブラリ管理。
エンコーダはBinXMLStreamから作成されます。入力はXMLテキストとみなされ、作成元のBinXMLStreamに対してエンコード済バイナリXMLを出力します。エンコーダはストリーミングSAXを使用してXMLテキストを読み取ります。XMLテキストのエンコーディングはXML解析の結果に基づいています。
エンコーディングがスキーマ対応か、スキーマレスかどうかを指定するエンコーダ上でschemaAwareフラグを設定します。
スキーマ対応のエンコーディングでは、特定のスキーマURLのスキーマがボキャブラリ・マネージャに登録されているかどうかをエンコーダが決定します。リポジトリベースまたはデータベースベースのプロセッサでは、エンコーダはリポジトリまたはデータベースに対して、スキーマURLに基づいてコンパイルされたスキーマを問い合せます。データベースでスキーマが使用可能である場合、バイナリXML形式でリポジトリまたはデータベースからフェッチされ、ローカルのボキャブラリ・マネージャに登録されます。ボキャブラリはスキーマです。
また、エンコーディングの結果が、スキーマに依存しないバイナリXMLストリームになるようにフラグを設定します。この場合、結果として生じるバイナリXMLストリームは、すべてのトークン定義インラインを含んでいて、スキーマまたは外部トークン・セットに依存していません。
エンコーディングがスキーマ対応の場合、エンコーダは、SAXストリームをより効率的にエンコーディングするためにスキーマ・オブジェクトからのデータ型情報を使用します。スキーマ組込みの各データ型には、関連付けられたデフォルトのエンコーディング・データ型があります。スキーマを使用するバイナリXMLストリーム・エンコーディングは、スキーマに関する少なくとも部分妥当性を前提としています(部分妥当性の場合、一意のキー、キー参照、IDまたはDREFに関する検証はありません)。スキーマに関してデータが完全に有効であることがわかっている場合、エンコード済バイナリXMLストリームにその情報が格納されます。
|
関連項目: バイナリ・エンコーディング・データ型と、そのXML Schemaデータ型からのマッピングに関する表は、『Oracle XML DB開発者ガイド』を参照してください。 |
テキストXMLに関連付けられたスキーマがない場合、テキストXML内で繰り返される項目について整数のトークンIDが生成されます。トークンIDとトークン定義の表を作成することは、重要な圧縮テクニックです。トークン定義はボキャブラリ・キャッシュ内にトークン表として格納されます。インライン・トークン定義のプロパティが設定されている場合、そのトークン定義は現在のインラインです。
エンコーダ上の別のプロパティは、PSVI(Post Schema Validated Infoset)情報をバイナリ・ストリームの一部として指定しています。これがtrueに設定されると、DOM上のPSVI用のXDK拡張APIを使用してPSVI情報にアクセスできます。psvi = trueの場合、入力XMLはスキーマに関して完全に検証されます。psviがfalseの場合、PSVI情報は出力バイナリ・ストリームに含まれません。デフォルトはfalseです。
バイナリXMLデコーダはバイナリXMLをXML infosetに変換します。デコーダはBinXMLStreamから作成されます。このストリームからバイナリXMLを読み取り、SAXイベントを出力するか、デコードされたXMLの読取りのためのPull型InfosetReader APIを提供します。スキーマがBinXMLStreamに関連付けられている場合、バイナリXMLデコーダは、デコーディングの前にボキャブラリIDを使用してボキャブラリ・キャッシュから関連付けられたスキーマ・オブジェクトを取得します。ボキャブラリ・キャッシュにスキーマがないが、サーバーへの接続情報はある場合、スキーマはサーバーからフェッチされます。
スキーマがBinXMLStreamに関連付けられていない場合、トークン定義はBinXMLStream内のインラインであっても、トークン・セットに格納されていてもかまいません。対応する名前空間のトークンが、ローカルなボキャブラリ・キャッシュの中に格納されていない場合、トークン・セットはリポジトリからフェッチされます。
バイナリXMLプロセッサはメタデータの場所(スキーマまたはトークン・セット)に応じて、ローカル・バイナリXMLプロセッサまたはリポジトリ・バイナリXMLプロセッサとなります。
メタデータの永続性を考慮して、DBバイナリXMLプロセッサを使用することをお薦めします。この場合、スキーマとトークン・セットはデータベースに登録されます。ボキャブラリ・マネージャはスキーマまたはトークン・セットをデータベースからフェッチし、エンコーディングとデコーディングのためにローカルのボキャブラリ・キャッシュにキャッシュします。
データベースでないパーシステントなメタデータ・リポジトリを使用する必要がある場合、独自のメタデータ・リポジトリにプラグインすることができます。このリポジトリBinXMLMetadataProviderで通信するためには、インタフェースを実装する必要があります。
スキーマは、ローカル・バイナリXMLプロセッサにローカルに登録します。ローカル・バイナリXMLプロセッサには、存続期間にユーザーにより送信されたすべてのスキーマを保持するボキャブラリ管理があります。ローカル・バイナリXMLプロセッサに関連付けられたボキャブラリ・マネージャは、スキーマに永続性を提供しません。
同一のスキーマ(スキーマの場所とターゲット名前空間が同一)を登録する場合、スキーマは解析されず、既存のボキャブラリIDが戻されます。ターゲット名前空間は同じでスキーマの場所が異なる新しいスキーマを登録すると、既存のスキーマ定義が増大した新しいスキーマ定義ができるか、競合エラーが発生します。
各スキーマはボキャブラリIDによって識別されます。ボキャブラリIDはプロセッサの有効範囲内にあり、プロセッサの範囲内で一意です。スキーマを使用して検証する文書はすべて、スキーマの最新バージョンを使用して検証する際に必要になります。
バイナリXML注釈は、スキーマ内の<xsd:appInfo>要素内にのみ出現できます。スキーマ注釈には、ユーザー・レベルとシステム・レベルの2つのカテゴリがあります。ボキャブラリ・マネージャは、スキーマ登録時にそれらを解釈します。他のすべての型の注釈(データベース関連の注釈など)は無視されます。
トークン・セットはデータベースまたはメタデータ・リポジトリからフェッチされ、ローカルなボキャブラリ・マネージャにキャッシュされて、デコーディング用途に使用できます。エンコーディング時には、永続性を考慮してトークン・セットをリポジトリにプッシュすることができます。
エンコーダ上にフラグを設定することで、トークン定義をバイナリXMLストリームの一部にも含めることができます。
BinXMLStreamクラスはバイナリXMLストリームを表します。バイナリXMLストリームに対して定義されている様々な格納場所を次に示します。
InputStream: 読取り用ストリーム
OutputStream: 書込み用ストリーム
URL: 読取り用ストリーム
File: 読み書き用ストリーム
BLOB: 読み書き用ストリーム
バイト配列: 読み書き用ストリーム
メモリー内: 読み書き用ストリーム
BinXMLStreamオブジェクトは、作成時に格納タイプを指定します。
BinXMLStreamオブジェクトはBinXMLProcessorファクトリから作成することができます。このファクトリは、JDBC接続(リモート・メタデータ・アクセスの場合)、接続プール、URLまたはPageManagerPool(遅延型メモリー内格納の場合)で初期化することができます。BinXMLEncoderおよびBinXMLDecoderは、エンコーディングまたはデコーディングのためにBinXMLStreamから作成できます。
1. リポジトリを持たないプロセッサを作成し、スキーマを登録し、XML SAXイベントをスキーマ対応のバイナリ形式にエンコードし、ファイルに格納する例を次に示します。
BinXMLProcessor proc = BinXMLProcessorFactory.createProcessor(); proc.registerSchema(schemaURL); BinXMLStream outbin = proc.createBinaryStream(outFile); BinXMLEncoder enc = outbin.getEncoder(); enc.setSchemaAware(true); ContentHandler hdlr = enc.getContentHandler();
ContentHandlerを取得できる他、次のように他のハンドラも取得できます。
LexicalHandler lexhdlr = enc.getLexicalHandler(); DTDHandler dtdhdlr = encenc.getDTDHandler(); DeclHandler declhdlr = enc.getDeclHandler(); ErrorHandler errhdlr = enc.getErrorHandler();
SAXイベントを生成するアプリケーションではhdlrを使用します。
2. データベース・リポジトリを持つプロセッサを作成し、スキーマ対応のバイナリ・ストリームをデコードし、Pull APIを使用してデコードされたXMLを読む例を次に示します。デコーディング用のスキーマはデータベース・リポジトリからフェッチされます。
DBBinXMLMetadataProvider dbrep =
BinXMLMetadataProviderFactory.createDBMetadataProvider();
BinXMLProcessor proc = BinXMLProcessorFactory.createProcessor(dbrep);
BinXMLStream inpbin = proc.createBinaryStream(blob);
BinXMLDecoder dec = inpbin.getDecoder();
InfosetReader xmlreader = dec.getReader();
デコーダからPull型でXMLを読み取るにはxmlreaderを使用します。
エンコーダがXML入力を取得すると、それはSAXイベントを使用して解析および読取りを受け、バイナリXMLを出力します。
エンコーディングの前に、スキーマ対応オプションとスキーマなしオプションのいずれかを指定することができます。デフォルトはスキーマなしエンコーディングです。スキーマ対応オプションを設定すると、エンコーディングはインスタンス・ドキュメントで指定されたスキーマに基づいて行われます。エンコーディングで使用された注釈付きスキーマは、デコーディング時にも必要になります。スキーマなしオプションを指定すると、エンコーディングはスキーマに依存しませんが、トークンはデフォルトでインラインです。デフォルトをオーバーライドするには、Inline-token = falseを設定します。
バイナリXMLデコーダはバイナリXMLストリームを入力に取り、出力としてSAXイベントを生成するか、デコードされたXMLを読み取るためのPull型インタフェースを提供します。スキーマ対応バイナリXMLストリームの場合、バイナリXMLデコーダはスキーマ情報を抽出するためにボキャブラリ・マネージャと対話します。
ボキャブラリ・マネージャに必須スキーマが含まれず、プロセッサのタイプが有効JDBC接続を伴うバイナリXML DBの場合、リモート・スキーマは、デコードされるバイナリXMLストリームのボキャブラリIDに基づいてデータベースまたはメタデータ・リポジトリからフェッチされます。同様に、トークン定義の集合をデータベースまたはメタデータ・リポジトリからフェッチすることができます。
プロセスのフローを次に示します。ボキャブラリがXML Schemaの場合、XML Schemaテキストを入力に取ります。Schema Annotatorはスキーマ・テキストにシステム・レベル注釈を付けます。スキーマにはすでに多少のユーザー・レベル注釈があることがあります。
結果として生じる注釈付きスキーマは、Schema Builderによって処理されてXML Schemaオブジェクトを構成します。このXML Schemaオブジェクトはボキャブラリ・キャッシュに格納されます。ボキャブラリ・キャッシュは各XML Schemaオブジェクトに一意のボキャブラリIDを割り当て、それが出力として戻されます。スキーマの注釈付きDOM表現がバイナリXMLエンコーダに送信されます。
エンコーディング時に、schemaAwareがtrueでプロパティImplcitSchemaRegistrationがtrueの場合、XMLインスタンス・ドキュメントのルート要素にある最初のxsi:schemaLocationタグは、そのスキーマをローカルのボキャブラリ・マネージャに自動的に登録します。他のすべてのschemaLocationタグは明示的に登録されません。プロセッサがデータベース指向の場合、メタデータ・リポジトリ・ベースのプロセッサと同様にスキーマもデータベース内に登録されています。
エンコーディングのschemaAwareがfalseに設定されるか、ImplcitSchemaRegistrationがfalseの場合、xsi:schemaLocationタグはエンコーダによってすべて無視されます。
DBBinXMLMetadataProviderオブジェクトは、スキーマやトークン・セットなどのボキャブラリ情報にアクセスするために、専用のJDBC接続または接続プールを使用してインスタンス化されます。また、XMLデータにアクセスするために、プロセッサは1つ以上のデータ接続を使用して関連付けられています。
バイナリXMLプロセッサは、バイナリXMLスキーマ、トークン・セットおよびバイナリXMLストリームの格納と取得など、様々なタイプのバイナリXML操作のためにデータベースと通信することができます。データベース通信は、次のような場面で使用されます。
スキーマURLのボキャブラリIDを使用したコンパイル済バイナリXMLスキーマの抽出
エンコーディングのためにコンパイル済バイナリXMLスキーマを取得する場合、スキーマURLに基づいてデータベースへの問合せが行われます。バイナリXMLスキーマのデコーディングでは、ボキャブラリIDに基づいてデータベースからスキーマをフェッチします。
スキーマURLの使用とボキャブラリIDの取得によるコンパイル済でないバイナリXMLスキーマの格納
エンコーディング時にxsi:schemaLocationタグに遭遇すると、データベースへの永続的な格納のためにスキーマがデータベースに登録されます。スキーマに関連付けられたボキャブラリIDは、コンパイル済スキーマのバイナリ・バージョンと同様、データベースから取得されます。コンパイル済スキーマ・オブジェクトが構成され、データベースから戻されたボキャブラリIDを使用してローカル・キャッシュに格納されます。
名前空間URLを使用したバイナリ・トークン・セットの取得
デコードされるバイナリ・ストリームがデコーディングのためにトークン表で関連付けられている場合、それらはメタデータ接続を使用してデータベースからフェッチされます。
名前空間URLを使用したバイナリ・トークン・セットの格納
XMLテキストをスキーマなしでエンコードすると、トークン定義のトークン・セットになります。これらのトークン表はデータベース内に永続的に格納されることができます。メタデータ接続は、トークン・セットをデータベースに転送するために使用されます。
リモート記憶域オプションを持つバイナリXMLストリーム
エンコーディングの結果を格納し、デコード用にバイナリXMLを取得するために、バイナリXMLを持つXMLType列が含まれた表は、ユーザーが作成します。データベースとの通信は、SQL*NetおよびJDBCで行うことができます。JDBC問合せの出力結果セットからXMLTypeオブジェクトをフェッチします。バイナリ・データを読み取るため、またはバイナリ・データを書き出すためのBinXMLStreamは、XMLTypeオブジェクトから作成することができます。バイナリXMLデータの読み書きをサポートするには、XMLTypeクラスを拡張する必要があります。
ローカルのボキャブラリ・マネージャおよびキャッシュは、BinXMLProcessorが存続する間、メモリーにメタデータ情報を格納します。BinXMLMetadataProviderインタフェースを実装してBinXMLProcessorにプラグインすることによって、メタデータの独自のバックエンド記憶域をプラグインします。現在のところ、メタデータ・プロバイダは各プロセッサにつき1つのみサポートされています。
BinXMLMetadataProviderインタフェースを実装するFileBinXMLMetadataProviderをコーディングする必要があります。エンコーダとデコーダはこれらのAPIを使用して、永続的なバックエンド記憶域からメタデータにアクセスします。永続的な記憶域の構成情報を設定します。たとえば、ファイル・システムの場合のルート・ディレクトリをFileBinXMLMetadataProviderクラスに設定します。FileBinXMLMetadataProviderをインスタンス化してBinXMLProcessorにプラグインします。