プライマリ・コンテンツに移動
Oracle® XML Developer's Kitプログラマーズ・ガイド
12c リリース1 (12.1) B71283-04
目次へ移動
目次
索引へ移動
索引

前
次

22 XML Schema Processor for Cの使用

この章では、Extensible Markup Language (XML) Schema Processor for Cの使用方法について説明します。

内容は次のとおりです。

注意:

Oracle XML Developer's Kit (XDK)およびOracle XML DBアプリケーションには、統合Cアプリケーション・プログラミング・インタフェース(API)を使用します。非統合の旧C関数は非推奨で、下位互換性のためにのみサポートされています。これは、将来のリリースでは削除される予定です。

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

22.1 XML Schema Processor for Cの概要

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」を参照してください。

22.1.1 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/: サンプル・コード

22.1.2 標準への準拠

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

  • W3CのXML 1.0勧告

  • W3CのDOMレベル1.0勧告

  • W3CのXML Namespace勧告

  • W3CのXML Schema勧告

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

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

表22-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

概要ファイル

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

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

含まれるライブラリ 説明

libxml10.a

XMLパーサー、Extensible Stylesheet Language Transformation (XSLT)プロセッサ、XML Schema Processor

libcore10.a

Common Oracle Runtime Environment (CORE)関数

libnls10.a

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

22.2 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/サブディレクトリにあります。

22.3 XML Schema Processor for Cの使用方法

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

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

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

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

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

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

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

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

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

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

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

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

表22-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

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

ストリーミング・バリデータは、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に渡す操作もサポートされます。

22.5.1 透明モードの使用

アプリケーションはXmlEvCreateSVCtx()の起動で開始します。この起動は、型がxmlctxであるイベント・コンテキストを作成して戻します。それ以降のすべてのストリーミング・バリデータの起動で、これを渡す必要があります。作成されたイベント・コンテキストは、XmlEvDestroyCtx()を起動して終了する必要があります。

アプリケーションはイベント・コンテキストの作成後、XmlEvNext()を起動することによって繰り返し次のイベントに検証を進め、この関数は次のイベントの型を戻します。アプリケーションはその他のAPIインタフェースにより、最後のイベントに関連する情報を取得します。

22.5.1.1 透明モードでのエラー処理

妥当なイベントという概念はありません。妥当性は文書のプロパティであって、個別の項目やイベントのプロパティではありません。エラーは次のとおりです。

  • XML_EVENT_FATAL_ERROR: XMLイベントの生産者がこのエラーを報告すると、ストリーミング・バリデータはこのイベントをアプリケーションに戻し、検証処理を停止します。

  • XML_EVENT_ERROR: 検証エラーが発生すると、ストリーミング・バリデータはこのイベントをアプリケーションに戻します。アプリケーションでXmlEvGetError()を起動してエラーの詳細を取得します。

アプリケーションがXML_EVENT_ERRORまたはXML_EVENT_FATAL_ERRORイベントを受信しなければ、ドキュメントは妥当です。このため、アプリケーションはこれらのイベントを処理する必要があります。無視してはいけません。

これらのエラーはキャッシュされないため、関連の情報を後から取得することはできません。

22.5.1.2 ストリーミング・バリデータの例

透明モードの例を示します。

例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);

22.5.2 不透明モードの使用

不透明モードでは、ストリーミング・バリデータは、検証対象のインスタンス・ドキュメントをプロデューサからの一連のイベントとして読み取りますが、アプリケーション(コンシューマ)にイベントを渡しません。成功時にはXMLERR_OK、失敗時にはエラーの数を戻します。

スキーマがロードされ、XMLイベント・コンテキストが初期化されると、アプリケーションはXmlEvSchemaValidate()を起動してこのモードで文書を検証することができます。この関数の署名はポインタをイベント・コンテキストに導きます。宣言は次のとおりです。

xmlerr XmlEvSchemaValidate(xmlctx *xctx, xsdctx *sctx, xmlevctx *evctx, 
       oratext **errmsg);
/* Returns (xmlerr), the error code */

22.5.2.1 不透明モードでのエラー処理

ストリーミング・バリデータでエラーが発生すると、XmlEvSchemaValidate()はエラー数を戻します。これには、解析エラーが原因の場合も検証エラーが原因の場合もあります。その後、アプリケーションは既存のXmlEvGetError APIを使用してエラー・メッセージを取得することができます。エラー・メッセージはパラメータ化されていて、通常、ストリーミング・バリデータが終了した地点までのすべてのエラーを含んでいます。

22.5.2.2 不透明モードのアプリケーションの例

不透明モードの例を示します。

例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);

22.5.3 既存のDOMでの関数XmlSchemaLoad()の使用

関数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);

22.5.4 検証オプション

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);