この章の内容は次のとおりです。
| 
 注意: 新規のXDKおよびOracle XML DBアプリケーションには、新規の統合C APIを使用してください。以前のC関数は非推奨です。下位互換性のみを目的としてサポートされていますが、今後は拡張されません。これは、将来のリリースでは削除される予定です。新しいCのAPIの詳細は、「統合C APIの概要」を参照してください。  | 
XML Schema Processor for Cは、XML Parser for Cとともに動作するコンポーネントです。XML Schema Processor for Cを使用すると、XMLアプリケーションで単純なデータ型および複雑なデータ型をサポートできます。
XML Schema Processor for Cは、W3CのXML Schema勧告をサポートしています。このため、XML文書を処理するカスタム・アプリケーションを簡単に作成できます。また、Oracleが移植されたすべてのオペレーティング・システムには、標準に準拠したXML SchemaプロセッサがXDKの一部として搭載されています。
XML Schema Processorでは、XMLの検証およびメタデータの取得が可能です。XML Processorはそれ自身またはXML Parser for Cによってコールできます。
XML Schema Processor for Cには、次の機能があります。
単純型および複合型をサポートします。
XML Parser for Cに統合されています。
W3CのXML Schema勧告をサポートします。
| 
 関連項目: 
  | 
XML Schema Processor for Cは、次の標準に準拠しています。
W3CのXML 1.0勧告
W3CのDOMレベル1.0勧告
W3CのXML Namespace勧告
W3CのXML Schema勧告
表20-1に、今回のリリースで提供されるファイルおよびディレクトリを示します。
表20-1 XML Schema Processor for C: $ORACLE_HOMEで提供されるファイル
| ディレクトリおよびファイル | 説明 | 
|---|---|
| 
 
  | 
 スキーマ・プロセッサが実行可能な  | 
| 
 
  | 
 XML/XSL/Schemaおよびサポート・ライブラリ  | 
| 
 
  | 
 グローバリゼーション・サポート・データ・ファイル  | 
| 
 
  | 
 スキーマ・プロセッサの使用例  | 
| 
 
  | 
 ヘッダー・ファイル  | 
| 
 
  | 
 エラー・メッセージ・ファイル  | 
| 
 
  | 
 概要ファイル  | 
表20-2に、ディレクトリlibに含まれるライブラリを示します。
XML Schema Processor for Cは、インストール場所のbin/schemaをコールすることによって、実行可能ファイルとしてコールされます。これは次の2つの引数を取ります。
XMLインスタンス・ドキュメント
デフォルト・スキーマ(オプション)
XML Schema Processor for Cは、提供されたAPIを使用するコードを記述して起動することもできます。このコードは、includeサブディレクトリにあるヘッダーを使用してコンパイルし、libサブディレクトリにあるライブラリにリンクする必要があります。プログラムを構築する方法の詳細は、xdk/demo/c/schemaサブディレクトリにあるMakefileを参照してください。
異なる言語のエラー・メッセージ・ファイルは、mesg/サブディレクトリにあります。
図20-1に、次に示すXML Schema Processor for Cのコール順序を示します。
初期化コールが、セッションの開始時に一度コールされ、セッションで使用されるスキーマ・コンテキストを戻します。
セッションで使用されるスキーマ・ドキュメントは事前にロードされます。
検証するインスタンス・ドキュメントが、まずXMLパーサーによって解析されます。
次に、このインスタンスのXML要素サブツリーの最上位がスキーマ検証関数に渡されます。
インスタンス・ドキュメントにスキーマが明示的に定義されていない場合は、任意の事前ロード済のスキーマが使用されます。
同じスキーマ・コンテキストを使用して、複数のドキュメントを検証できます。
セッションが終了すると、スキーマ・メモリー解放関数がコールされます。これによって、ロードされたスキーマに対して割り当てられていたすべてのメモリーが解放されます。
ディレクトリxdk/demo/c/schemaには、Oracle XML Schema ProcessorとそのAPIの使用方法を示すサンプルXML Schemaアプリケーションがあります。表20-3に、提供されるサンプル・ファイルを示します。
表20-3 XML Schema for Cのサンプル
| サンプル・ファイル | 説明 | 
|---|---|
| 
 
  | 
 サンプル・プログラムを作成および実行し、適切な出力を確認するMakeファイル  | 
| 
 
  | 
 XML Schema for CのAPIをコールするプログラム  | 
| 
 
  | 
 
  | 
| 
 
  | 
 
  | 
| 
 
  | 
 
  | 
サンプル・プログラムを作成するには、makeコマンドを実行します。
プログラムを作成および実行し、実際の出力と予想される出力を比較するには、次を実行します。
make sure
ストリーミング・バリデータは11gリリース1(11.1)で導入されました。ストリーミング・バリデータはXMLイベントを使用します。XMLイベントはSAXイベントに類似した、XML文書の表現です。XMLイベントには開始タグ、終了タグおよびコメントがあります。生産者がSAXイベントを駆動し、消費者がXMLイベントを駆動します。ストリーミング・バリデータは古いスキーマ・バリデータとソフトウェアを共有し、大部分の機能をそこから導出します。メモリー・オーバーヘッドは、古いバリデータで使用されていたDOM表現より少なくなります。検証は文書に対して1回のみ行われます。
ストリーミングの検証には次の2つのモードがあります。
透明モード: イベントはアプリケーションに戻されます。
不透明モード: イベントはアプリケーションに戻されませんが、文書検証処理の成功または失敗を示すエラーが戻されます。
文書検証の前に、通常の検証コンテキストを作成し、そのコンテキストを使用して関連のスキーマをロードする必要があります。次に、Pull Parser用(または別のイベント生産者用)のXMLイベント・コンテキストを作成する必要があります。これによりこのイベント・コンテキストがストリーミング・バリデータに指定され、生産者からイベントをリクエストすることができるようになります。
スキーマDOM内でXmlSchemaLoad APIに渡す操作もサポートされます。
最初にアプリケーションがXmlEvCreateSVCtx()をコールします。このコールは型がxmlctxであるイベント・コンテキストを作成して戻します。それ以降のすべてのコールでは、これをストリーミング・バリデータに渡す必要があります。作成されたイベント・コンテキストは、末尾にXmlEvDestroyCtx()のコールを持つ必要があります。
アプリケーションはイベント・コンテキストの作成後、XmlEvNext()のコールを発行することによって繰り返し次のイベントに検証を進め、この関数は次のイベントの型を戻します。アプリケーションはその他のAPIインタフェースにより、最後のイベントに関連する情報を取得します。
妥当なイベントという概念はありません。妥当性は文書のプロパティであって、個別の項目やイベントのプロパティではありません。エラーは次のとおりです。
XML_EVENT_FATAL_ERROR: XMLイベントの生産者がこのエラーを報告すると、ストリーミング・バリデータはこのイベントをアプリケーションに戻し、検証処理を停止します。
XML_EVENT_ERROR: 検証エラーが発生すると、ストリーミング・バリデータはこのイベントをアプリケーションに戻します。アプリケーションはXmlEvGetError()をコールして、エラーに関する詳細情報を入手することができます。
アプリケーションがXML_EVENT_ERRORまたはXML_EVENT_FATAL_ERRORイベントを受信しなければ、文書は妥当です。このため、アプリケーションはこれらのイベントを処理する必要があります。無視してはいけません。
これらのエラーはキャッシュされないため、関連の情報を後から取得することはできません。
透明モードの例を示します。
例20-1 ストリーミング・バリデータの透明モード
# include "xmlev.h"
...
xmlevctx *ppevtcx, *svevctx;
xmlctx *xctx
xsdctx *sctx;
if (!(xctx = XmlCreate(&xerr, (oratext *) "test")))
    printf("Failed to create XML context, error %u\n",
                        (unsigned) xerr);
...
if (!(sctx = XmlSchemaCreate(xctx, &xerr, NULL)))
    printf("Failed to create schema context, error %u\n",
                        (unsigned) xerr);
...
If (xerr = XmlSchemaLoad(sctx, "my_schema.xsd", NULL))
    printf("Failed to load schema, error %u\n",
                        (unsigned) xerr);
if(!(ppevctx = XmlEvCreatePPCtx(xctx, &xerr, NULL)))
   printf("Failed to create EVENT context, error %u\n",
                        (unsigned) xerr);
if(xerr = XmlEvLoadPPDoc(xctx, ppevctx, "file", "test.xml", 0, NULL))
   printf("Failed to load Document, error %u\n",
                        (unsigned) xerr);
...
If(!(svevctx = XmlEvCreateSVCtx(xctx, sctx, ppevctx, &xerr)))
   printf("Failed to create SVcontext, error %u\n",
                        (unsigned) xerr);
...
for(;;)
{
   xmlevtype cur_event;
   cur_event = XmlEvNext(svevctx);
   switch(cur_event)
    {
        case XML_EVENT_FATAL_ERROR:
           printf("FATAL ERROR");
           /* error processing goes here */
           return;
        case XML_EVENT_ERROR:
           XmlEvGetError(svevctx, oratext *msg);
           printf("Validation Failed, Error %s\n", msg);
           break;
        case XML_EVENT_START_ELEMENT:
           printf("<%s>", XmlEvGetName(svevctx));
           break;
...
        case XML_EVENT_END_DOCUMENT:
           printf("END DOCUMENT");
           return;
    }
}
...
XmlEvDestroySVCtx(svevctx);
XmlSchemaDestroy(sctx);
XmlEvDestroyCtx(ppevctx);
XmlDestroyCtx(xctx);
不透明モードでは、ストリーミング・バリデータは、検証対象のインスタンス・ドキュメントを生産者からの一連のイベントとして読み取りますが、アプリケーション(消費者)にイベントを渡しません。成功時にはXMLERR_OK、失敗時にはエラーの数を戻します。
スキーマがロードされ、XMLイベント・コンテキストが初期化されると、アプリケーションはXmlEvSchemaValidate()をコールしてこのモードで文書を検証することができます。この関数の署名はポインタをイベント・コンテキストに導きます。宣言は次のとおりです。
xmlerr XmlEvSchemaValidate(xmlctx *xctx, xsdctx *sctx, xmlevctx *evctx,
       oratext **errmsg);
/* Returns (xmlerr), the error code */
 ストリーミング・バリデータでエラーが発生すると、XmlEvSchemaValidate()はエラー数を戻します。これには、解析エラーが原因の場合も検証エラーが原因の場合もあります。その後、アプリケーションは既存のXmlEvGetError APIを使用してエラー・メッセージを取得することができます。エラー・メッセージはパラメータ化されていて、通常、ストリーミング・バリデータが終了した地点までのすべてのエラーを含んでいます。
不透明モードの例を示します。
例20-2 ストリーミング・バリデータの不透明モードの例
# include "xmlev.h"
...
xmlevctx *ppevtcx;
xmlctx   *xctx;
xsdctx   *sctx;
oratext  **errmsg;
xmlerr   xerr;
if (!(xctx = XmlCreate(&xerr, (oratext *) "test"))
      printf("Failed to create XML context, error %u\n", (unsigned) xerr);
...
if (!(sctx = XmlSchemaCreate(xctx, &xerr, NULL)))
      printf("Failed to create schema context, error %u\n", (unsigned) xerr);
...
if (xerr = XmlSchemaLoad(sctx, "my_schema.xsd", NULL))
    printf("Failed to load schema, error %u\n", (unsigned) xerr);
if(!(ppevctx = XmlEvCreatePPCtx(xctx, &xerr, NULL)))
     printf("Failed to create EVENT context, error %u\n", (unsigned) xerr);
if(xerr = XmlEvLoadPPDoc(xctx, ppevctx, "file", "test.xml", 0, NULL))
   printf("Failed to load Document, error %u\n", (unsigned) xerr);
if((xerr = XmlEvSchemaValidate(xctx, sctx, ppevctx, errmsg)))
{
  printf("Validation Failed, Error: %s\n", errmsg);
}
...
XmlSchemaDestroy(sctx);
XmlEvDestroyCtx(ppevctx);
XmlDestroyCtx(xctx);
XmlSchemaLoad()は、既存のDOMとともに動作するように11gリリース1(11.1)で拡張されました。以前は、この関数は2つの固定引数と、1つの変数プロパティ・セットを取りました。最初の引数はスキーマ・コンテキスト、2番目の引数はスキーマ文書のURLの場所です。URLを指定されたスキーマDOMへのアクセスを可能にするため、変数引数のセットに新しいプロパティが追加されました。プロパティschema_dom_callbackは、アプリケーションによって提供されるコールバック関数です。提供される場合、スキーマ・ロード関数はこのコールバックを使用してDOMにアクセスし、メイン・スキーマ、インクルード済スキーマ、インポート済スキーマおよび再定義済スキーマをロードします。コールバック署名は次のとおりです。
typedef  xmldocnode* (*xmlsch_dom_callback) (xmlctx *xctx, oratext *uri,
         xmlerr *xerr);
このコールバックはURIを受け入れ(スキーマ・ロード関数が目的の文書のURI内で渡します)、文書ノードを戻します。次に例を示します。
例20-3 XmlSchemaLoad()の例
# include "xmlev.h"
...
xmlctx *xctx;
xsdctx *sctx;
xmldocnode *doc;
if (!(xctx = XmlCreate(&xerr, (oratext *) "test"))
    printf("Failed to create XML context, error %u\n", (unsigned) xerr);
...
if (!(sctx = XmlSchemaCreate(xctx, &xerr, NULL)))
    printf("Failed to create schema context, error %u\n", (unsigned) xerr);
...
If (xerr = XmlSchemaLoad(sctx, schema_uri, "schema_dom_callback", func1,  NULL))
    printf("Failed to load schema, error %u\n", (unsigned) xerr);
...
XmlSchemaDestroy(sctx);
XmlDestroyCtx(xctx);
XmlSchemaSetValidateOptions()を使用して検証処理のオプションを指定することができます。次に例を示します。
XmlSchemaSetValidateOptions(scctx, "ignore_id_constraint", (boolean)TRUE, NULL);
オプションは次のとおりです。
ignore_id_constraint(11.1の前から存在)
ignore_sch_location(11.1の前から存在)
ignore_par_val_rest(11.1の前から存在)
ignore_pattern_check: このプロパティがTRUEの場合、ストリーミング・バリデータはパターン・ファセット・チェックを無視します。デフォルトはFALSEです。
no_events_for_defaults: このプロパティがTRUEの場合、ストリーミング・バリデータはインスタンス・ドキュメントに追加されたデフォルト値のイベントを戻しません。このオプションは透明モードの場合のみ使用できます。
例20-4 新しいオプションを使用するストリーミング・バリデータの例
# include "xmlev.h"
...
xmlevctx *ppevtcx;
xmlctx   *xctx;
xsdctx   *sctx;
xmlerr   xerr;
oratext  **errmsg;
if (!(xctx = XmlCreate(&xerr, (oratext *) "test"))
    printf("Failed to create XML context, error %u\n", (unsigned) xerr);
...
if (!(sctx = XmlSchemaCreate(xctx, &xerr, NULL)))
    printf("Failed to create schema context, error %u\n", (unsigned) xerr);
...
If (xerr = XmlSchemaLoad(sctx, "my_schema.xsd", NULL))
    printf("Failed to load schema, error %u\n", (unsigned) xerr);
if(!(ppevctx = XmlEvCreatePPCtx(xctx, &xerr, "file", "test.xml", NULL)))
   printf("Failed to create EVENT context, error %u\n", (unsigned) xerr);
if(xerr = XmlEvLoadPPDoc(xctx, ppevctx, "file", "test.xml", 0, NULL))
   printf("Failed to load Document, error %u\n", (unsigned) xerr);
XmlSchemaSetValidateOptions(sctx, "ignore_id_constraint", TRUE,
                                  "ignore_pattern_facet", TRUE, NULL);
if((xerr = XmlEvSchemaValidate(xctx,sctx, ppevctx, errmsg)))
{
  printf("Validation Failed, Error: %s\n", errmsg);
}
...
XmlSchemaDestroy(sctx);
XmlEvDestroyCtx(ppevctx);
XmlDestroyCtx(xctx);