この章では、JavaでのバイナリExtensible Markup Language(バイナリXML)の使用方法について説明します。
内容は次のとおりです。
バイナリXMLは、Oracle 11gリリース1(11.1)で導入された機能です。バイナリXMLを使用すると、XMLテキストと圧縮バイナリXMLの間でのエンコードおよびデコードが可能になります。効率の点から、Document Object Model (DOM)およびSimple API for XML (SAX)アプリケーション・プログラミング・インタフェース(API)が、XMLアプリケーションによって直接使用されるためにバイナリXMLの上位に提供されます。XML文書のフラグメントの圧縮と解凍により、インクリメンタル処理が促進されます。
この章では、XML Parser for Javaを十分に理解していると想定します。
関連項目:
XMLType
記憶域オプションは、XML文書をバイナリ形式で格納するために提供されています。この記憶域オプションは、既存のキャラクタ・ラージ・オブジェクト(CLOB
)オプションおよびオブジェクト・リレーショナル記憶域オプションに追加されるものです。バイナリXML記憶域オプションを使用して、XMLType
の表および列を作成することができます。バイナリ形式のXMLデータは、XMLType
を操作する既存のすべてのStructured Query Language (SQL)の演算子と関数、Procedural Language/Structured Query Language (PL/SQL) APIによってアクセスおよび操作できます。
バイナリXMLは、XMLデータの簡潔なXMLスキーマ対応エンコーディングですが、XMLスキーマに基づいていないXMLデータで使用することもできます。データベース外にあるXMLデータについても(たとえばクライアント側アプリケーションで)バイナリXMLを使用することができます。バイナリXMLを使用すると、テキストからバイナリ、およびバイナリからテキストへのXML文書のエンコーディングおよびデコーディングが可能です。バイナリXMLはネイティブなデータベース・データ型を持つ解析後の永続的なXMLです。
バイナリXMLでは、非構造化記憶域より効率的なデータベースの格納、更新、索引付け、問合せ性能およびフラグメント抽出が可能です。データとメタデータは一緒に、または分けて格納することができます。
関連項目:
Oracle XML DBのすべての記憶域モデルの説明は、『Oracle XML DB開発者ガイド』を参照してください。
バイナリXML for Javaにはいくつかの使用モデルがあります。次のサブセクションで、バイナリXMLの使用に関する用語とモデルについて説明します。
バイナリXMLの使用に関連する用語を次に示します。
文書ID: エンコード済の各XML文書は、一意の文書IDにより識別されます。これは、16バイトのグローバル・ユーザー識別子(GUID)またはURLなどの不透明なバイト列です。
トークン表: テキストXML文書に、関連付けられたスキーマがない場合、繰返し項目の容量を最小化するためにトークン(または記号)表が使用されます。
ボキャブラリID: スキーマID、またはトークン表の名前空間Universal Resource Identifier (URI)です。
スキーマID: バイナリXMLプロセッサを有効範囲とするスキーマの一意の不透明なバイナリID。スキーマIDはバイナリXMLプロセッサに対して一意で、そのバイナリXMLプロセッサの有効範囲内でのみ識別可能です。スキーマIDは、スキーマが拡張された場合も不変です。スキーマIDは、インポートされたスキーマやインクルードされたスキーマなどを含むスキーマ文書セットの全体を表します。
スキーマ・バージョン: 注釈付きのスキーマにはすべて、それに関連付けられたバージョン番号があります。バージョン番号はシステム・レベルの注釈の一部として指定されます。スキーマが拡張されると(つまり、同一のスキーマの新しいバージョンがそのバイナリXMLプロセッサに登録されると)、バイナリXMLプロセッサによって増分されます。
部分妥当性: バイナリXMLのスキーマを使用するストリーム・エンコーディングは、スキーマに関する少なくとも部分妥当性を前提としています。部分妥当性は、一意のキー、キー参照、識別子(ID)またはIDREFなどのDTD属性の検証がないことを示します。
これはバイナリXMLの最も単純な使用例です。単一のバイナリXMLプロセッサがあります。使用可能なリポジトリは、永続的でなく、バイナリXMLプロセッサが存在する間のみ使用できる、ローカルなインメモリー・ボキャブラリ・キャッシュのみです。すべてのスキーマはあらかじめエンコーディング前にバイナリXMLプロセッサに登録される必要がありますが、XMLプロセッサがxsi:SchemaLocation
タグを認識したときに自動登録させることもできます。デコーディングの場合、スキーマはボキャブラリ・キャッシュですでに使用可能です。
異なるバイナリXMLプロセッサでデコーディングが発生する場合は、ここで説明する様々なWebサービスを参照してください。
この使用例では、バイナリXMLプロセッサはJava Database Connectivity (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に変換します。
バイナリXMLデコーディング: バイナリXMLデコーダはバイナリXMLをXML infosetに変換します。
スキーマ管理、トークン管理などのバイナリXMLボキャブラリ管理。
エンコーダはBinXMLStream
から作成されます。XMLテキストを入力として取り、作成元のBinXMLStream
にエンコード済バイナリXMLを出力します。エンコーダは、ストリーミングSAXを使用してXMLテキストを読み取ります。XMLテキストのエンコーディングは、XML解析の結果に基づいています。
エンコーディングがスキーマ対応か、スキーマレスかどうかを指定するエンコーダ上でschemaAware
フラグを設定します。
スキーマ対応のエンコーディングでは、指定されたスキーマURLのスキーマがボキャブラリ・マネージャに登録されているかどうかをエンコーダが決定します。リポジトリベースまたはデータベースベースのプロセッサでは、エンコーダはリポジトリまたはデータベースに対して、スキーマURLに基づいてコンパイルされたスキーマを問い合せます。データベースでスキーマが使用可能である場合、バイナリXML形式でリポジトリまたはデータベースからフェッチされ、ローカルのボキャブラリ・マネージャに登録されます。ボキャブラリはスキーマです。
また、エンコーディングによってスキーマに依存しないバイナリXMLストリームが生成されることを示すフラグを設定します。この場合、結果として生じるバイナリXMLストリームは、すべてのトークン定義インラインを含んでいて、スキーマまたは外部トークン・セットに依存していません。
エンコーディングがスキーマ対応の場合、エンコーダは、SAXストリームをより効率的にエンコーディングするためにスキーマ・オブジェクトからのデータ型情報を使用します。スキーマ組込みの各データ型には、関連付けられたデフォルトのエンコーディング・データ型があります。スキーマを使用するバイナリXMLストリーム・エンコーディングは、スキーマに関する少なくとも部分妥当性を前提としています(部分妥当性の場合、一意のキー、キー参照、IDまたはIDREFなどのDTD属性に関する検証はありません)。スキーマでデータが完全に有効であることがわかっている場合、エンコード済バイナリ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はプロセッサの有効範囲内にあり、プロセッサの範囲内で一意です。スキーマを使用して検証する文書はすべて、スキーマの最新バージョンを使用して検証する際に必要になります。
バイナリXML注釈は、スキーマ内の<xsd:appInfo>
要素内にのみ出現できます。スキーマ注釈には、ユーザー・レベルとシステム・レベルの2つのカテゴリがあります。ボキャブラリ・マネージャは、スキーマ登録時にそれらを解釈します。他のすべての型の注釈(データベース関連の注釈など)は無視されます。
これらの注釈は登録の前にユーザーによって指定されます。
encodingType
: この注釈はxsd:element
、xsd:attribute
またはxsd:simpleType
要素の中で使用できます。要素または属性のノード値をエンコードするために使用されるデータ型を示します。文字列に関しては、このリリースでは8ビット・エンコーディングのUnicode (UTF-8)エンコーディングのサポートのみがあります。
BinXMLStream
クラスはバイナリXMLストリームを表します。バイナリXMLストリームに対して定義されている様々な格納場所を次に示します。
InputStream
: 読取り用ストリーム
OutputStream
: 書込み用ストリーム
URL
: 読取り用ストリーム
File
: 読み書き用ストリーム
BLOB
: 読み書き用ストリーム
バイト配列: 読み書き用ストリーム
メモリー内: 読み書き用ストリーム
BinXMLStream
オブジェクトは、作成時に格納タイプを指定します。
BinXMLStream
オブジェクトはBinXMLProcessor
ファクトリから作成することができます。このファクトリは、JDBC接続(リモート・メタデータ・アクセスの場合)、接続プール、URLまたはPageManagerPool
(遅延型メモリー内格納の場合)で初期化することができます。BinXMLEncoder
およびBinXMLDecoder
は、エンコーディングまたはデコーディングのためにBinXMLStream
から作成できます。
リポジトリを持たないプロセッサを作成し、スキーマを登録し、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の場合、リモート・スキーマは、デコードされるバイナリXMLストリームのボキャブラリIDに基づいてデータベースまたはメタデータ・リポジトリからフェッチされます。同様に、トークン定義の集合をデータベースまたはメタデータ・リポジトリからフェッチすることができます。
プロセスのフローを次に示します。ボキャブラリがXMLスキーマの場合、入力としてXMLスキーマ・テキストを取ります。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操作のためにデータベースと通信することができます。データベース通信は、次のような場面で使用されます。
ボキャブラリIDまたはスキーマURLを使用したコンパイル済バイナリXMLスキーマの抽出
エンコーディングのためにコンパイル済バイナリXMLスキーマを取得する場合、スキーマURLに基づいてデータベースへの問合せが行われます。バイナリXMLスキーマのデコーディングでは、ボキャブラリIDに基づいてデータベースからスキーマをフェッチします。
スキーマURLの使用とボキャブラリIDの取得によるコンパイル済でないバイナリXMLスキーマの格納。
エンコーディング時にxsi:schemaLocation
タグが見つかると、データベースへの永続的な格納のためにスキーマがデータベースに登録されます。スキーマに関連付けられたボキャブラリIDは、コンパイル済スキーマのバイナリ・バージョンと同様、データベースから取得されます。コンパイル済スキーマ・オブジェクトが構成され、データベースから戻されたボキャブラリIDを使用してローカル・キャッシュに格納されます。
名前空間URLを使用したバイナリ・トークン・セットの取得。
デコードされるバイナリ・ストリームがデコーディングのためにトークン表で関連付けられている場合、それらはメタデータ接続を使用してデータベースからフェッチされます。
名前空間URLを使用したバイナリ・トークン・セットの格納
XMLテキストをスキーマなしでエンコードすると、トークン定義のトークン・セットが生成されます。これらのトークン表はデータベース内に永続的に格納されることができます。メタデータ接続は、トークン・セットをデータベースに転送するために使用されます。
リモート記憶域オプションを持つバイナリXMLストリーム
エンコーディングの結果を格納し、デコード用にバイナリXMLを取得するために、バイナリXMLを持つXMLType
列が含まれた表は、ユーザーが作成します。データベースとの通信は、Oracle Net ServicesおよびJDBCで行うことができます。JDBC問合せの出力結果セットからXMLType
オブジェクトをフェッチします。バイナリ・データを読み取るため、またはバイナリ・データを書き出すためのBinXMLStream
は、XMLType
オブジェクトから作成することができます。バイナリXMLデータの読み書きをサポートするには、XMLType
クラスを拡張する必要があります。
ローカルのボキャブラリ・マネージャおよびキャッシュは、BinXMLProcessor
が存続する間、メモリーにメタデータ情報を格納します。BinXMLMetadataProvider
インタフェースを実装してBinXMLProcessor
にプラグインすることによって、メタデータの独自のバックエンド記憶域をプラグインします。現在のところ、メタデータ・プロバイダは各プロセッサにつき1つのみサポートされています。
BinXMLMetadataProvider
インタフェースを実装するFileBinXMLMetadataProvider
をコーディングする必要があります。エンコーダとデコーダはこれらのAPIを使用して、永続的なバックエンド記憶域からメタデータにアクセスします。永続的な記憶域の構成情報を設定します。たとえば、ファイル・システムの場合のルート・ディレクトリをFileBinXMLMetadataProvider
クラスに設定します。FileBinXMLMetadataProvider
をインスタンス化してBinXMLProcessor
にプラグインします。