この章では、Extensible Markup Language (XML) Schema Processor for Cの使用方法について説明します。
内容は次のとおりです。
注意:
Oracle XML Developer's Kit (XDK)およびOracle XML DBアプリケーションには、統合Cアプリケーション・プログラミング・インタフェース(API)を使用します。非統合の旧C関数は非推奨で、下位互換性のためにのみサポートされています。これは、将来のリリースでは削除される予定です。
統合C APIの詳細は、「統合C APIの概要」を参照してください。
XML Schema Processor for Cは、Extensible Markup Language (XML) Parser for Cとともに動作するコンポーネントです。XML Schema Processor for Cを使用すると、XMLアプリケーションで単純なデータ型および複雑なデータ型をサポートできます。
XML Schema Processor for Cは、World Wide Web Consortium (W3C)のXML Schema勧告をサポートしています。このため、XML文書を処理するカスタム・アプリケーションを簡単に作成できます。また、Oracle Databaseが移植された各オペレーティング・システムには、標準に準拠したXML SchemaプロセッサがXDKの一部として搭載されています。
XML Schema Processorでは、XMLの検証およびメタデータの取得が可能です。これは、それ自身またはXML Parser for Cによってコールできます。
関連項目:
XML Schemaの詳細およびXML Schemaを使用する理由の詳細は、「XML Parsing for Java」を参照してください。
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/
: サンプル・コード
Schema Processorは、次の標準に準拠しています。
W3CのXML 1.0勧告
W3CのDOMレベル1.0勧告
W3CのXML Namespace勧告
W3CのXML Schema勧告
表22-1に、今回のリリースで提供されるファイルおよびディレクトリを示します。
表22-1 XML Schema Processor for C: $ORACLE_HOMEで提供されるファイル
ディレクトリおよびファイル | 説明 |
---|---|
|
スキーマ・プロセッサが実行可能な |
|
XML/XSL/Schemaおよびサポート・ライブラリ |
|
グローバリゼーション・サポート・データ・ファイル |
|
スキーマ・プロセッサの使用例 |
|
ヘッダー・ファイル |
|
エラー・メッセージ・ファイル |
|
概要ファイル |
表22-2に、ディレクトリlib
に含まれるライブラリを示します。
表22-2 XML Schema Processor for C: 提供されるライブラリ
含まれるライブラリ | 説明 |
---|---|
|
XMLパーサー、Extensible Stylesheet Language Transformation (XSLT)プロセッサ、XML Schema Processor |
|
Common Oracle Runtime Environment (CORE)関数 |
|
グローバリゼーション・サポート |
XML Schema Processor for Cは、インストール場所のbin/schema
をコールすることによって、実行可能ファイルとしてコールされます。これは次の2つの引数を取ります。
XMLインスタンス・ドキュメント
デフォルト・スキーマ(オプション)
XML Schema Processor for Cは、提供されたAPIを使用するコードを記述して起動することもできます。このコードは、include
サブディレクトリにあるヘッダーを使用してコンパイルし、lib
サブディレクトリにあるライブラリにリンクする必要があります。プログラムを構築する方法の詳細は、xdk/demo/c/schema
サブディレクトリにあるMakefile
を参照してください。
異なる言語のエラー・メッセージ・ファイルは、mesg/
サブディレクトリにあります。
図22-1に、次に示すXML Schema Processor for Cのコール順序を示します。
初期化コールが、セッションの開始時に一度コールされ、セッションで使用されるスキーマ・コンテキストを戻します。
セッションで使用されるスキーマ・ドキュメントは事前にロードされます。
検証するインスタンス・ドキュメントが、まずXMLパーサーによって解析されます。
次に、このインスタンスのXML要素サブツリーの最上位がスキーマ検証関数に渡されます。
インスタンス・ドキュメントにスキーマが明示的に定義されていない場合は、任意のロード済のスキーマが使用されます。
同じスキーマ・コンテキストを使用して、複数のドキュメントを検証できます。
セッションが終了すると、スキーマ・メモリー解放関数がコールされます。これによって、ロードされたスキーマに対して割り当てられていたすべてのメモリーが解放されます。
ディレクトリxdk/demo/c/schema
には、Oracle XML Schema ProcessorとそのAPIの使用方法を示すサンプルXML Schemaアプリケーションがあります。表22-3に、提供されるサンプル・ファイルを示します。
表22-3 XML Schema for Cのサンプル
サンプル・ファイル | 説明 |
---|---|
|
サンプル・プログラムを作成および実行し、適切な出力を確認するMakeファイル。 |
|
XML Schema for CのAPIをコールするプログラム |
|
|
|
|
|
|
サンプル・プログラムを作成するには、make
コマンドを実行します。
プログラムを作成および実行し、実際の出力と予想される出力を比較するには、次を実行します。
make sure
ストリーミング・バリデータは、Oracle Database 11g リリース1(11.1)で導入されました。Simple API for XML (SAX)イベントに類似した、XML文書の表現である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
イベントを受信しなければ、ドキュメントは妥当です。このため、アプリケーションはこれらのイベントを処理する必要があります。無視してはいけません。
これらのエラーはキャッシュされないため、関連の情報を後から取得することはできません。
透明モードの例を示します。
例22-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を使用してエラー・メッセージを取得することができます。エラー・メッセージはパラメータ化されていて、通常、ストリーミング・バリデータが終了した地点までのすべてのエラーを含んでいます。
不透明モードの例を示します。
例22-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()
は、2つの固定引数と1つの変数プロパティ・セットを受け入れます。最初の引数はスキーマ・コンテキスト、2番目の引数はスキーマ文書のURLの場所です。
Oracle Database 11gリリース1(11.1)以上で、プロパティschema_dom_callback
を使用して、URLを指定されたスキーマDOMへのアクセスを提供できます。このプロパティは、アプリケーションによって提供されるコールバック関数です。提供される場合、スキーマ・ロード関数はこのコールバックを使用してDOMにアクセスしてメイン・スキーマをロードし、インクルード済スキーマ、インポート済スキーマおよび再定義済スキーマにアクセスします。
コールバック署名は次のとおりです。
typedef xmldocnode* (*xmlsch_dom_callback) (xmlctx *xctx, oratext *uri, xmlerr *xerr);
このコールバックはURIを受け入れ(スキーマ・ロード関数が目的の文書のURI内で渡します)、文書ノードを戻します。例22-3に、これを示します。
例22-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
の場合、ストリーミング・バリデータはインスタンス・ドキュメントに追加されたデフォルト値のイベントを戻しません。このオプションは透明モードの場合のみ使用できます。
例22-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);