ヘッダーをスキップ
Oracle® XML Developer's Kitプログラマーズ・ガイド
11gリリース2 (11.2)
B56264-06
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

20 XML Schema Processor for Cの使用

この章の内容は次のとおりです。


注意:

新規のXDKおよびOracle XML DBアプリケーションには、新規の統合C APIを使用してください。以前のC関数は非推奨です。下位互換性のみを目的としてサポートされていますが、今後は拡張されません。これは、将来のリリースでは削除される予定です。

新しいCのAPIの詳細は、「統合C APIの概要」を参照してください。


XML Schema Processor for Cの概要

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 Parser for Cによってコールできます。


関連項目:

XML Schemaの詳細およびXML Schemaを使用する理由の詳細は、第4章「XML Parsing for Java」を参照してください。

XML Schema Processor for Cの機能

XML Schema Processor for Cには、次の機能があります。

  • 単純型および複合型をサポートします。

  • XML Parser for Cに統合されています。

  • W3CのXML Schema勧告をサポートします。


関連項目:

  • 『Oracle Database XML C APIリファレンス』の「C用のスキーマAPIパッケージ」

  • $ORACLE_HOME/xdk/demo/c/schema/: サンプル・コード


標準への準拠

XML Schema Processor for Cは、次の標準に準拠しています。

  • W3CのXML 1.0勧告

  • W3CのDOMレベル1.0勧告

  • W3CのXML Namespace勧告

  • W3CのXML Schema勧告

XML Schema Processor for C: 提供されるソフトウェア

表20-1に、今回のリリースで提供されるファイルおよびディレクトリを示します。

表20-1 XML Schema Processor for C: $ORACLE_HOMEで提供されるファイル

ディレクトリおよびファイル 説明

bin

スキーマ・プロセッサが実行可能なschema

lib

XML/XSL/Schemaおよびサポート・ライブラリ

nls/data

グローバリゼーション・サポート・データ・ファイル

xdk/demo/c/schema

スキーマ・プロセッサの使用例

xdk/include

ヘッダー・ファイル

xdk/mesg

エラー・メッセージ・ファイル

xdk/readme.html

概要ファイル


表20-2に、ディレクトリlibに含まれるライブラリを示します。

表20-2 XML Schema Processor for C: 提供されるライブラリ

含まれるライブラリ 説明

libxml10.a

XML Parser、XSLT Processor、XML Schema Processor

libcore10.a

COREファンクション

libnls10.a

グローバリゼーション・サポート


C XML Schema Processorコマンドライン・ユーティリティの使用

XML Schema Processor for Cは、インストール場所のbin/schemaをコールすることによって、実行可能ファイルとしてコールされます。これは次の2つの引数を取ります。

  • XMLインスタンス・ドキュメント

  • デフォルト・スキーマ(オプション)

XML Schema Processor for Cは、提供されたAPIを使用するコードを記述して起動することもできます。このコードは、includeサブディレクトリにあるヘッダーを使用してコンパイルし、libサブディレクトリにあるライブラリにリンクする必要があります。プログラムを構築する方法の詳細は、xdk/demo/c/schemaサブディレクトリにあるMakefileを参照してください。

異なる言語のエラー・メッセージ・ファイルは、mesg/サブディレクトリにあります。

XML Schema Processor for Cの使用方法

図20-1に、次に示すXML Schema Processor for Cのコール順序を示します。

  1. 初期化コールが、セッションの開始時に一度コールされ、セッションで使用されるスキーマ・コンテキストを戻します。

  2. セッションで使用されるスキーマ・ドキュメントは事前にロードされます。

  3. 検証するインスタンス・ドキュメントが、まずXMLパーサーによって解析されます。

  4. 次に、このインスタンスのXML要素サブツリーの最上位がスキーマ検証関数に渡されます。

  5. インスタンス・ドキュメントにスキーマが明示的に定義されていない場合は、任意の事前ロード済のスキーマが使用されます。

  6. 同じスキーマ・コンテキストを使用して、複数のドキュメントを検証できます。

  7. セッションが終了すると、スキーマ・メモリー解放関数がコールされます。これによって、ロードされたスキーマに対して割り当てられていたすべてのメモリーが解放されます。

図20-1 XML Schema Processor for Cの使用方法

図20-1の説明が続きます
「図20-1 XML Schema Processor for Cの使用方法」の説明

XML Schema Processor for Cサンプル・プログラムの実行

ディレクトリxdk/demo/c/schemaには、Oracle XML Schema ProcessorとそのAPIの使用方法を示すサンプルXML Schemaアプリケーションがあります。表20-3に、提供されるサンプル・ファイルを示します。

表20-3 XML Schema for Cのサンプル

サンプル・ファイル 説明

Makefile

サンプル・プログラムを作成および実行し、適切な出力を確認するMakeファイル。

xsdtest.c

XML Schema for CのAPIをコールするプログラム

car.{xsd,xml,std}

xsdtestを実行した後のサンプル・スキーマ、インスタンス・ドキュメントおよび予想される出力

aq.{xsd,xml,std}

xsdtestを実行した後の2つ目のサンプル・スキーマ、インスタンス・ドキュメントおよび予想される出力

pub.{xsd,xml,std}

xsdtestを実行した後の3つ目のサンプル・スキーマ、インスタンス・ドキュメントおよび予想される出力


サンプル・プログラムを作成するには、makeコマンドを実行します。

プログラムを作成および実行し、実際の出力と予想される出力を比較するには、次を実行します。

make sure

ストリーミング・バリデータの概要

ストリーミング・バリデータは、Oracle Database 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()関数の拡張

XmlSchemaLoad()は、既存のDOMとともに動作するようにOracle Database 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 (Oracle Database 11g リリース1(11.1)よりも前から存在する)

  • ignore_sch_location (Oracle Database 11g リリース1(11.1)よりも前から存在する)

  • ignore_par_val_rest (Oracle Database 11g リリース1(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);