ヘッダーをスキップ
Oracle XML Developer's Kitプログラマーズ・ガイド
10gリリース3(10.1.3)
B28611-01
  目次
目次
索引
索引

戻る
戻る
次へ
次へ
 

14 XML Parser for C

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

XDKおよびOracle XML DBに対応した統合C APIの概要

単一のDOMは統合C API(XML用のC API)の一部です。XMLがデータベース内にあるか、データベース外部のドキュメントにあるかどうかは関係ありません。DOMは、DOM 2.0に、XML文書に対応するXDKの非標準拡張機能か、一般にパフォーマンス向上のため、表にXMLType列として格納されたXMLに対応するOracle XML DBの非標準拡張機能を追加したものです。


注意:

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

統合C APIは、XSLTとXML Schemaをプライマリ・カスタマとして使用して、XDKおよびOracle XML DBで必要なすべての機能を集めたプログラム・インタフェースです。DOM 2.0標準にできるだけ準拠していますが、オブジェクト指向のDOM仕様からフラットなCの名前空間へマッピングする際に、一部の名前を変更する必要がありました(オーバーロードされたgetName()メソッドをgetAttrName()に変更するなど)。

準拠するコンテキストによって関数の統合が実現されます。最上位のXMLコンテキスト(xmlctx)は、連動するXMLコンポーネント間で共通の情報を共有していました。このコンテキストでは、データ・エンコーディング、エラー・メッセージ言語、低水準メモリー割当てコールバックなどが定義されます。文書を解析してDOMまたはSAXで出力する前に、この情報が必要です。

XDKおよびOracle XML DBのどちらにおいても、両方のコンテキスト(最上位コンテキストおよびサービス・コンテキスト)に対し、異なる起動およびメモリー解放関数が必要です。初期化関数は実装固有の引数を取り、準拠するコンテキストを戻します。準拠するコンテキストとは、戻されたコンテキストがxmlctxで始まる必要があることを意味します。この標準ヘッダーの後に、実装固有の追加部分が続く場合があります。

初期化(xmlctxを取得すること)は実装固有の手順です。xmlctxを取得すると、統合されたDOMコールを使用し、すべてのコールにおいてxmlctxを最初の引数として使用します。

このインタフェース(リリース10.1の新機能)は既存のC APIの後継です。特に、oraxmlインタフェース(最上位、DOM、SAXおよびXSLT)およびoraxsd(Schema)インタフェースは使用できなくなりました。

XDKのDOMの使用

XMLが従来のファイル・システムまたはWebなどにある場合、XDKパッケージが使用されます。この場合も同様に、起動にのみ実装固有の手順があります。

まず、最上位のxmlctxが必要です。このコンテキストには、エンコーディング情報、低水準メモリー・コールバック、エラー・メッセージ言語、エンコーディングなど(つまり、すべてのXDKコンポーネントにおいて一貫している必要がある要素)が含まれます。XmlCreate()xmlctxを割り当てます。

xmlctx *xctx;
xmlerr  err;

xctx = (xmlctx *) XmlCreate(&err, "xdk context", "data-encoding", "ascii", ..., NULL);

高水準のXMLコンテキストを取得すると、ドキュメントをロードして、DOMイベントを生成できます。次のようにDOMイベントを生成します。

xmldocnode *domctx;
xmlerr err;

domctx = XmlLoadDom(xctx, &err, "file", "foo.xml", NULL);

SAXイベントを生成するにはSAXコールバック構造が必要です。

xmlsaxcb saxcb = {
  UserAttrDeclNotify,             /* user's own callback functions */
  UserCDATANotify,
  ...
  };

if (XmlLoadSax(xctx, &saxcb, NULL, "file", "foo.xml", NULL) != 0)
  /*    an error occured  */

XMLコンテキストxmlctxのメモリー解放関数はXmlDestroy()です。

C APIを使用したXML文書のロード

xmlctxを取得すると、XmlLoadDom()関数またはXmlLoadSax()関数を使用して、シリアライズされたXML文書がロードされます。ドキュメント・ノードがある場合、すべてのAPI DOM関数が使用可能です。

C APIに対応するXML文書のデータ・エンコーディング

XMLデータは多くのエンコーディングに存在します。エンコーディングは次の3つの方法で制御できます。

  • 自己記述的でないファイルに対して前提とするデフォルト・エンコーディングの指定

  • DOMまたはSAXの表示用エンコーディングの指定

  • DOMがシリアライズされている場合の再エンコーディング

入力データは常にエンコードされています。UTF-16など、エンコーディングによっては完全に自己記述的なものがあり、この場合は実際のデータの開始前に特定のBOMが必要です。XMLDeclまたはMIMEヘッダーでも文書のエンコーディングを指定できます。特定のエンコーディングを決定できない場合、デフォルトの入力エンコーディングが適用されます。デフォルトを指定していない場合、ASCIIプラットフォームではUTF-8、EBCDICプラットフォームではUTF-Eが想定されます。

入力文書のエンコーディング情報が不正である場合に備えて、対策が取られています。たとえば、encoding=asciiと記述されているXMLDeclが含まれるASCII文書が無分別にEBCDICに変換された場合、新しいEBCDIC文書には、(EBCDIC内に)文書ASCIIであると誤って主張するXMLDeclが含まれます。XMLデータを再エンコードするプログラムの正しい動作は、XMLDeclの変換ではなく、これを再生成することです。XMLDeclは、データそのものではなく、メタデータです。しかし、このルールは無視されることが多く、不正な文書が生成されます。この問題を回避するため、入力エンコーディングの強制的な設定を可能にする追加フラグが提供され、不正なXMLDeclの問題が解決されています。

入力エンコーディングを決定するための優先順位ルールは、次のとおりです。

1. ユーザーが指定した強制エンコーディング。


注意:

競合が存在する場合、強制エンコーディングによって致命的エラーになる可能性があります。たとえば、入力文書がUTF-16であり、UTF-16 BOMで始まっているにもかかわらず、ユーザーが強制UTF-8エンコーディングを指定したとします。この場合、パーサーによって競合に関するエラーが発行されます。

2. プロトコル仕様(HTTPヘッダーなど)。

3. XMLDecl仕様の使用。

4. ユーザーのデフォルト入力エンコーディング。

5. デフォルト: UTF-8(ASCIIプラットフォームの場合)、UTF-E(EBCDICプラットフォームの場合)。

入力エンコーディングが決定されると、文書の解析およびデータの表示が可能になります。表示用エンコーディングを選択できます。元の入力エンコーディングにかかわらず、データにはこの表示用エンコーディングが実行されます。

シリアライズ形式でDOMを書き戻す時点で、表示用データの再エンコードを選択でき、最終的にシリアライズされた文書を任意のエンコーディングにすることができます。

ヌル文字終了および長さエンコードのC API関数

Cにおけるネイティブな文字列表現はヌル文字で終了します。そのため、プライマリDOMインタフェースではヌル文字で終了する文字列が使用され、戻されます。ただし、Oracle XML DBデータが表形式で格納されている場合、ヌル文字で終了するのではなく、長さがエンコードされます。したがって、頻度の高い場合にパフォーマンスを向上させるために、長さエンコードAPIの追加セットが提供されます(これらの使用は意図的に選択できます)。どちらの関数のセットも機能します。

特に、起動する頻度の高い次のDOM関数には2つのAPIがあります。

表14-1 ヌル文字終了および長さエンコードのC API関数

ヌル文字終了API 長さエンコードAPI

XmlDomGetNodeName()

XmlDomGetNodeNameLen()

XmlDomGetNodeLocal()

XmlDomGetNodeLocalLen()

XmlDomGetNodeURI()

XmlDomGetNodeURILen()

XmlDomGetNodeValue()

XmlDomGetNodeValueLen()

XmlDomGetAttrName()

XmlDomGetAttrNameLen()

XmlDomGetAttrLocal()

XmlDomGetAttrLocalLen()

XmlDomGetAttrURI()

XmlDomGetAttrURILen()

XmlDomGetAttrValue()

XmlDomGetAttrValueLen()


エラー処理

API関数では、通常、数値のエラー・コード(成功の場合は0(ゼロ)、失敗の場合は0(ゼロ)以外)が戻されるか、または変数によりエラー・コードが戻されます。いずれの場合も、エラー・コードが格納され、XmlDomGetLastError()で最新のエラーを取得できます。

デフォルトでは、エラー・メッセージはstderrに出力されます。ただし、初期化の際にエラー・メッセージ・コールバックを登録できます。エラーが発生すると、コールバックが起動し、エラーは出力されません。

C APIのインストール

特別なインストールや最初に使用するための要件はありません。XML DOMにORACLE_HOMEは不要です。これは、縮小されたルート・ディレクトリ(OTNリリースで提供される場合など)の外で実行できます。

ただし、XML DOMにはグローバリゼーション・サポートが必要であるため、グローバリゼーション・サポート・データ・ファイルが存在し、環境変数ORACLE_HOMEまたはORA_NLS10によってこのファイルが検出される必要があります。

OCIおよびC APIの使用

データベースのXMLType列にXMLのC APIを使用できます。環境ハンドル、サービス・ハンドル、エラー・ハンドルおよびオプションのパラメータなどのOCIハンドルの値を初期化することにより、Oracle Call Interface(OCI)プログラムでデータベース表に格納されているXMLデータにアクセスできます。これらの入力値をOCIXmlDbInitXmlCtx()関数に渡すと、XMLコンテキストを戻します。C APIをコールした後、OCIXmlDbFreeXmlCtx()関数によってコンテキストが解放されます。

XMLコンテキスト

XMLコンテキストは、すべてのC DOM API関数における必須パラメータです。この不透明なコンテキストは、データ・エンコーディング、エラー・メッセージ言語などに関する情報をカプセル化します。XMLコンテキストの内容は、XDKアプリケーションとOracle XML DBアプリケーションでは異なります。


注意:

XML DBアプリケーションでXDK用のXMLコンテキストを使用したり、XDKアプリケーションでXML DB用のXMLコンテキストを使用しないでください。

Oracle XML DBでは、XMLコンテキストを初期化および解放する2つのOCI関数があり、プロトタイプは次のとおりです。

xmlctx *OCIXmlDbInitXmlCtx (OCIEnv *envhp, OCISvcCtx *svchp, OCIError *errhp,
       ocixmldbparam *params, ub4 num_params);

void OCIXmlDbFreeXmlCtx (xmlctx *xctx);


関連資料:

  • 関数の参考資料については、『Oracle Call Interfaceプログラマーズ・ガイド』のOCI XML DB関数に関する項を参照してください。

  • XMLのOCIサポートの詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』のXMLのOCIサポートに関する項を参照してください。

  • 『Oracle XML APIリファレンス』のC用のDOM APIに関する項を参照してください。


クライアント上でのXMLTypeインスタンスの作成

XmlLoadDom()コールを使用して、クライアントに新しいXMLTypeインスタンスを構築できます。「XDKのDOMの使用」の例に示されているように、最初にxmlctxを初期化する必要があります。XMLデータ自体は、ユーザー・バッファ、ローカル・ファイルまたはURIのいずれかから構築できます。これらの場所からの戻り値は(xmldocnode *)であり、残りの共通C APIで使用できます。最後に、(xmldocnode *)を(void *)にキャストし、必要に応じて直接バインド値として提供できます。

XmlCreateDocument()コールを使用して、空のXMLTypeインスタンスを構築できます。これは、他のタイプに対するOCIObjectNew()に相当します。前のコールで戻された(xmldocnode *)について操作し、バインド値として提供される必要がある場合、最後にこれを(void *)にキャストできます。

サーバー上のXMLデータ

サーバー上のXMLデータは、OCI文のコールによって操作できます。他のオブジェクト・インスタンスと同様に、xmldocnodeを使用してXMLType値をバインドして定義できます。OCI文を使用して、サーバーからXMLデータを選択できます。このデータは、C DOM関数で直接使用できます。同様に、SQL文に直接値をバインドできます。

XMLType関数および説明

次の表に、XML操作に使用する関数の一部を示します。

表14-2 XMLType関数

説明 関数名

空のXMLTypeインスタンスの作成

XmlCreateDocument()

ソース・バッファからの作成

XmlLoadDom()など

XPath式の抽出

XmlXPathEvalexpr()およびファミリ

XSLスタイルシートを使用した変換

XmlXslProcess()およびファミリ

XPathの有無のチェック

XmlXPathEvalexpr()およびファミリ

文書がスキーマベースかどうかの確認

XmlDomIsSchemaBased()

スキーマ情報の取得

XmlDomGetSchema()

文書の名前空間の取得

XmlDomGetNodeURI()

スキーマを使用した検証

XmlSchemaValidate()

XMLTypeからのDOMの取得

(void *)(xmldocnode *)へのキャスト

DOMからのXMLTypeの取得

(xmldocnode *)(void *)へのキャスト


OCIの例

次に、DOM APIを使用してスキーマ・ベース文書を構築し、データベースに保存する方法の例を示します(ヘッダー・ファイルxml.hおよびocixmldb.hをインクルードする必要があります)。

#include <xml.h>
#include <ocixmldb.h>
static oratext tlpxml_test_sch[] = "<TOP xmlns='example1.xsd'\n\
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' \n\
xsi:schemaLocation='example1.xsd example1.xsd'/>";

void example1()
{
    OCIEnv *envhp;
    OCIError *errhp;
    OCISvcCtx *svchp;
    OCIStmt *stmthp;
    OCIDuration dur;
    OCIType *xmltdo;

    xmldocnode  *doc;
    ocixmldbparam params[1];
    xmlnode *quux, *foo, *foo_data;
    xmlerr       err;

    /* Initialize envhp, svchp, errhp, dur, stmthp */
    /* ........ */

    /* Get an xml context */
    params[0].name_ocixmldbparam = XCTXINIT_OCIDUR;
    params[0].value_ocixmldbparam = &dur;
    xctx = OCIXmlDbInitXmlCtx(envhp, svchp, errhp, params, 1);

    /* Start processing */
    printf("Supports XML 1.0: %s\n",
       XmlHasFeature(xctx, (oratext *) "xml", (oratext *) "1.0") ?
                     "YES" : "NO");

    /* Parsing a schema-based document */
    if (!(doc = XmlLoadDom(xctx, &err, "buffer", tlpxml_test_sch,
                          "buffer_length", sizeof(tlpxml_test_sch)-1,
                          "validate", TRUE, NULL)))
    {
       printf("Parse failed, code %d\n");
       return;
    }

    /* Create some elements and add them to the document */
    top = XmlDomGetDocElem(xctx, doc);
    quux = (xmlnode *) XmlDomCreateElem(xctx ,doc, (oratext *) "QUUX");
    foo = (xmlnode *) XmlDomCreateElem(xctx, doc, (oratext *) "FOO");
    foo_data = (xmlnode *) XmlDomCreateText(xctx, doc, (oratext *)"foo's data");
    foo_data = XmlDomAppendChild(xctx, (xmlnode *) foo, (xmlnode *) foo_data);
    foo = XmlDomAppendChild(xctx, quux, foo);
    quux = XmlDomAppendChild(xctx, top, quux);

    XmlSaveDom(xctx, &err, top, "stdio", stdout, NULL);
    XmlSaveDom(xctx, &err, doc, "stdio", stdout, NULL);

    /* Insert the document to my_table */
    ins_stmt = "insert into my_table values (:1)";

    status = OCITypeByName(envhp, errhp, svchp, (const text *) "SYS",
                   (ub4) strlen((char *)"SYS"), (const text *) "XMLTYPE",
                   (ub4) strlen((char *)"XMLTYPE"), (CONST text *) 0,
                   (ub4) 0, dur, OCI_TYPEGET_HEADER,
                   (OCIType **) &xmltdo)) ;

    if (status == OCI_SUCCESS)
    {
       exec_bind_xml(svchp, errhp, stmthp, (void *)doc, xmltdo, ins_stmt));
    }

   /* free xml ctx */
   OCIXmlDbFreeXmlCtx(xctx);
}

/*--------------------------------------------------------*/
/* execute a sql statement which binds xml data */
/*--------------------------------------------------------*/
sword exec_bind_xml(svchp, errhp, stmthp, xml, xmltdo, sqlstmt)
OCISvcCtx *svchp;
OCIError *errhp;
OCIStmt *stmthp;
void *xml;
OCIType *xmltdo;
OraText *sqlstmt;
{
   OCIBind *bndhp1 = (OCIBind *) 0;
   OCIBind *bndhp2 = (OCIBind *) 0;
   sword  status = 0;
   OCIInd ind = OCI_IND_NOTNULL;
   OCIInd *indp = &ind;

   if(status = OCIStmtPrepare(stmthp, errhp, (OraText *)sqlstmt,
                    (ub4)strlen((char *)sqlstmt),
                    (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) {
     return OCI_ERROR;
   }

   if(status = OCIBindByPos(stmthp, &bndhp1, errhp, (ub4) 1, (dvoid *) 0,
                   (sb4) 0, SQLT_NTY, (dvoid *) 0, (ub2 *)0,
                   (ub2 *)0, (ub4) 0, (ub4 *) 0, (ub4) OCI_DEFAULT)) {
     return OCI_ERROR;
   }

   if(status = OCIBindObject(bndhp1, errhp, (CONST OCIType *) xmltdo,
               (dvoid **) &xml, (ub4 *) 0, (dvoid **) &indp, (ub4 *) 0)) {
     return OCI_ERROR;
   }

   if(status = OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0,
                (CONST OCISnapshot*) 0, (OCISnapshot*) 0, (ub4) OCI_DEFAULT)) {
     return OCI_ERROR;
  }

   return OCI_SUCCESS;
}

次に、DOM APIを使用し、データベースから文書を取得して変更する方法の例を示します。

#include <xml.h>
#include <ocixmldb.h>
sword example2()
{
    OCIEnv *envhp;
    OCIError *errhp;
    OCISvcCtx *svchp;
    OCIStmt *stmthp;
    OCIDuration dur;
    OCIType *xmltdo;

    xmldocnode  *doc;
    xmlnodelist *item_list; ub4 ilist_l;
    ocixmldbparam params[1];
    text *sel_xml_stmt = (text *)"SELECT xml_col FROM my_table";
    ub4    xmlsize = 0;
    sword  status = 0;
    OCIDefine *defnp = (OCIDefine *) 0;

    /* Initialize envhp, svchp, errhp, dur, stmthp */
    /* ........ */

    /* Get an xml context */
    params[0].name_ocixmldbparam = XCTXINIT_OCIDUR;
    params[0].value_ocixmldbparam = &dur;
    xctx = OCIXmlDbInitXmlCtx(envhp, svchp, errhp, params, 1);

    /* Start processing */
    if(status = OCITypeByName(envhp, errhp, svchp, (const text *) "SYS",
                   (ub4) strlen((char *)"SYS"), (const text *) "XMLTYPE",
                   (ub4) strlen((char *)"XMLTYPE"), (CONST text *) 0,
                   (ub4) 0, dur, OCI_TYPEGET_HEADER,
                   (OCIType **) xmltdo_p)) {
       return OCI_ERROR;
    }

    if(!(*xmltdo_p)) {
       printf("NULL tdo returned\n");
       return OCI_ERROR;
    }

    if(status = OCIStmtPrepare(stmthp, errhp, (OraText *)selstmt,
                    (ub4)strlen((char *)selstmt),
                    (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)) {
      return OCI_ERROR;
    }

    if(status = OCIDefineByPos(stmthp, &defnp, errhp, (ub4) 1, (dvoid *) 0,
                   (sb4) 0, SQLT_NTY, (dvoid *) 0, (ub2 *)0,
                   (ub2 *)0, (ub4) OCI_DEFAULT)) {
       return OCI_ERROR;
    }

    if(status = OCIDefineObject(defnp, errhp, (OCIType *) *xmltdo_p,
                            (dvoid **) &doc,
                            &xmlsize, (dvoid **) 0, (ub4 *) 0)) {
      return OCI_ERROR;
    }

    if(status = OCIStmtExecute(svchp, stmthp, errhp, (ub4) 1, (ub4) 0,
                 (CONST OCISnapshot*) 0, (OCISnapshot*) 0, (ub4) OCI_DEFAULT)) {
      return OCI_ERROR;
    }

    /* We have the doc. Now we can operate on it */
    printf("Getting Item list...\n");

   item_list = XmlDomGetElemsByTag(xctx,(xmlelemnode *) elem,(oratext *)"Item");
    ilist_l   = XmlDomGetNodeListLength(xctx, item_list);
    printf(" Item list length = %d \n", ilist_l);

    for (i = 0; i < ilist_l; i++)
    {
      elem = XmlDomGetNodeListItem(xctx, item_list, i);
      printf("Elem Name:%s\n", XmlDomGetNodeName(xctx, fragelem));
      XmlDomRemoveChild(xctx, fragelem);
    }

    XmlSaveDom(xctx, &err, doc, "stdio", stdout, NULL);

   /* free xml ctx */
   OCIXmlDbFreeXmlCtx(xctx);

   return OCI_SUCCESS;
}

XML Parser for Cの使用

XML Parser for Cは、Oracle DatabaseおよびOracle Application Serverに付属しています。これは、http://www.oracle.com/technology/tech/xmlからダウンロードして入手することもできます。

UNIXシステムの場合、$ORACLE_HOME/xdk/にあります。

ソフトウェア・アーカイブのdocディレクトリにあるreadme.htmlには、不具合の修正や追加のAPIなどのリリース固有の情報が含まれています。

XML Parser for Cは、XML文書が整形式であるかどうか、およびDTDに対して妥当であるかどうか(オプション)を確認します。このパーサーは、DOMインタフェースを介してアクセス可能なオブジェクト・ツリーを構築するか、SAXインタフェースを介して順次操作します。

質問、コメントまたは不具合の報告を、http://www.oracle.com/technology/tech/xmlXML Discussion Forumに投稿できます。

仕様に関するいくつかの情報ソースがあります。


関連資料:

  • 『Oracle XML APIリファレンス』のC用のDOM APIに関する項

  • 『Oracle XML APIリファレンス』のC用のSAX APIに関する項

  • 『Oracle XML APIリファレンス』のC用のコールバックAPIに関する項

  • 『Oracle XML APIリファレンス』のC用のデータ型に関する項

  • http://www.oracle.com/technology/tech/xml/


メモリー割当て

独自のメモリー割当てを使用する場合、メモリー・コールバック関数XML_ALLOC_FおよびXML_FREE_Fを使用できます。これらを使用する場合、どちらの関数も指定する必要があります。

SAXコールバック関数に渡されたパラメータに割り当てられたメモリー、またはDOM解析ツリーとともに格納されたノードおよびデータに割り当てられたメモリーは、次のいずれかが行われるまで解放されません。

  • XmlFreeDocument()をコールします。

  • XmlDestroy()をコールします。

スレッド・セーフティ

コールの初期化/解析/終了シーケンスのどこかでスレッドが分岐している場合、不適切な動作および結果が発生する場合があります。

データ型の索引

表14-3に、XML Parser for Cで使用するデータ型を示します。

表14-3 XML Parser for Cで使用するデータ型

データ型 説明

oratext

文字列ポインタ

xmlctx

マスターXMLのコンテキスト

xmlsaxcb

SAXコールバック構造(SAXのみ)

ub4

32ビット以上の符号なし整数

uword

ネイティブな符号なし整数


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

エラー・メッセージ・ファイルは、$ORACLE_HOME/xdk/mesgディレクトリにあります。環境変数ORA_XML_MESGを設定して、mesgサブディレクトリへの絶対パスを指定することもできます。ただし、これは必須ではありません。

XML Parser for Cのコール順序

図14-1に、次のようなXML Parser for Cのコール順序を示します。

  1. XmlCreate()関数は解析プロセスを初期化します。

  2. 解析項目はXML文書(ファイル)または文字列バッファのどちらかです。XmlLoadDom()関数を使用して、入力を解析します。

  3. DOMまたはSAX API

    DOM: DOMインタフェースを使用する場合は、次の手順が必要です。

    • XmlLoadDom()関数はXmlDomGetDocElem()をコールします。

    • この最初の手順により、必要に応じて他のDOM関数がコールされます。通常、これらの他の関数は、DOM文書を出力するノード関数または出力関数です。

    • XmlFreeDocument()を最初に起動し、解析プロセス中に作成されたすべてのデータ構造を削除できます。

    SAX: SAXインタフェースを使用する場合は、次の手順が必要です。

    • コールバック関数でXmlLoadSax()からのパーサーの結果を処理します。

    • コールバック関数を登録します。不要なSAXコールバック関数は、すべてNULLに設定できることに注意してください。

  4. XmlFreeDocument()を使用して、解析中に使用されたメモリーと構造を削除し、手順5.に進むか、手順2.に戻ります。

  5. XmlDestroy()を使用して解析プロセスを終了します。

パーサーのコール順序

パーサーのコール順序は次のいずれかになります。

  • XmlCreate() - XmlLoadDom() - XmlDestroy()

  • XmlCreate() - XmlLoadDom() - XmlFreeDocument() -

    XmlLoadDom() - XmlFreeDocument() - ... - XmlDestroy()

  • XmlCreate() - XmlLoadDom() -... - XmlDestroy()

図14-1 XML Parser for Cのコール順序

図14-1の説明が続きます
「図14-1 XML Parser for Cのコール順序」の説明

XML Parser for Cのデフォルト動作

XML Parser for Cのデフォルト動作は、次のとおりです。

DOM APIとSAX APIの比較

Oracle XML Parser for Cは、XML文書が整形式であるかどうか、およびDTDに対して妥当であるかどうか(オプション)を確認します。このパーサーは、次のいずれかのインタフェースでアクセス可能なオブジェクト・ツリーを構築します。

SAX APIの使用

SAXを使用するには、xmlsaxcb構造を関数ポインタで初期化し、これをXmlLoadSax()コールに渡します。ユーザー定義のコンテキスト構造へのポインタも含めることができます。このコンテキスト・ポインタは各SAX関数に渡されます。

SAXコールバック構造

SAXコールバック構造については次の関連資料を参照してください。


関連資料:

『Oracle XML APIリファレンス』のSAXに関する項

コマンドラインの使用方法

XML ParserおよびXSLT Processorは、bin/xmlを起動することによって、実行可能ファイルとしてコールできます。

xml [options] [document URI]
or
xml -f [options] [document filespec]

表14-4に、コマンドライン・オプションを示します。

表14-4 XML ParserおよびXSLT Processor: コマンドライン・オプション

オプション 説明
-B BaseUri

XSLTプロセッサ用のベースURIを設定します。http://pqr/xsl.txtBaseUriは、pqr.txtを解釈してhttp://pqr/pqr.txtに変換します。

-c

準拠の確認のみ。検証は行いません。

-e encoding

入力ファイルのエンコーディングを指定します。

-E encoding

DOMまたはSAXエンコーディングを指定します。

-f

ファイル: URIではなくfilespecを解析します。

-G xptrexprs

ファイルに指定されたXPointerスキーマの例を評価します。

-h

ヘルプ: 使用方法を表示します。(詳細なオプションの場合は-hh)。

-hh

詳細なオプションのリストを表示します。

-i n

XSLTプロセスを繰り返す回数。

-l language

エラーを報告する言語。

-n

数: DOMを全検索し、要素の数を報告します。

-o XSLoutfile

XSLTプロセッサの出力ファイルを指定します。

-p

解析後の文書とDTDの構造を出力します。

-P

ルート要素から整形して出力します。

-PE encoding

-Pまたは-PPの出力のエンコーディングを指定します。

-PP

ルート・ノード(DOC)からXMLDeclを含めて整形して出力します。

-PX

常に出力にXMLDeclを含めます。

-r

XSLT処理の<xsl:output>命令を無視しません。

-s stylesheet

XSLTスタイルシートを指定します。

-v

バージョン: パーサーのバージョンを表示し、終了します。

-V var value

C XSLTで最上位の変数をテストします。

-w

空白: すべての空白を保持します。

-W

警告: 警告の後で解析を停止します。

-x

SAXインタフェースを実行し、文書を出力します。


提供されるAPIを使用するためのCコードの記述

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

サンプル・ファイルの使用

$ORACLE_HOME/xdk/demo/c/ディレクトリには、DOMインタフェースおよびSAXインタフェースによるXML Parser for Cの使用方法を示すいくつかのXMLアプリケーションがあります。

サンプル・プログラムを作成するには、ディレクトリをサンプル・ディレクトリ(UNIXの場合$ORACLE_HOME/xdk/demo/c/)に変更して、READMEファイルを参照してください。このファイルには、サンプル・プログラムの作成方法が記載されています。

表14-5に、サンプル・ファイルを示します。

表14-5 XML Parser for Cのサンプル・ファイル

サンプル・ファイル名 説明

DOMNamespace.c

DOMNamespaceプログラムのソース。

DOMNamespace.std

DOMNamespaceからの予想される出力。

DOMSample.c

DOMSampleプログラムのソース。

DOMSample.std

DOMSampleからの予想される出力。

FullDOM.c

DOMインタフェースの使用例。

FullDOM.std

FullDOMからの予想される出力。

Makefile

サンプル・プログラムを作成するためのバッチ・ファイル。

NSExample.xml

名前空間を使用したサンプルXMLファイル。

SAXNamespace.c

SAXNamespaceプログラムのソース。

SAXNamespace.std

SAXNamespaceからの予想される出力。

SAXSample.c

SAXSampleプログラムのソース。

SAXSample.std

SAXSampleからの予想される出力。

XSLSample.c

XSLSampleプログラムのソース。

XSLSample.std

XSLSampleからの予想される出力。

XVMSample.c

XVMSampleプログラムのソース。

XVMSample.std

XVMSampleからの予想される出力。

XSLXPathSample.c

XSLXPathSampleプログラムのソース。

XSLXPathSample.std

XSLXPathSampleプログラムからの予想される出力。

XVMXPathSample.c

XVMXPathSampleプログラムのソース。

XVMXPathSample.std

XVMXPathSampleプログラムからの予想される出力。

class.xml

XSLSampleで使用できるXMLファイル。

iden.xsl

XSLSampleで使用できるスタイルシート。

cleo.xml

『The Tragedy of Antony and Cleopatra』(シェイクスピア戯曲のXMLバージョン)。


表14-6に、サンプル・ファイルで作成されるプログラムを示します。

表14-6 XML Parser for C: サンプル作成プログラム

作成プログラム 説明

DOMSample

DOM APIを使用するサンプル・アプリケーション(Cleopatraの概要、つまりXML要素のACTおよびSCENEを示します)。

SAXSample word

SAX APIを使用するサンプル・アプリケーション。用語を指定すると、その用語を含むCleopatraの戯曲のすべての行を表示します。用語を指定しない場合は、deathが使用されます。

DOMNamespace

DOMインタフェースを使用する点を除き、SAXNamespaceと同じです。

SAXNamespace

SAX APIに名前空間による拡張を使用するサンプル・アプリケーション。NSExample.xmlのすべての要素と属性、および名前空間に関するすべての情報が出力されます。

FullDOM

DOMインタフェース全体の使用例。すべてのコールを実行します。

XSLSample xmlfile xslss

XSLプロセッサの使用例。入力として、XMLファイルおよびXSLスタイルシートの2つのファイル名を取ります。

XVMSample xmlfile xslfile

XSLT Virtual Machineおよびコンパイラの使用例。入力として、XMLファイルおよびXSLスタイルシートの2つのファイルを取ります。

XSLXPathSample xmlfile xpathexpr

XSL/XPathプロセッサの使用例。入力として、XMLファイルおよびXPath式を取ります。評価されたXPath式の結果を生成します。

XVMXPathSample xmlfile xpathexpr

XSLT Virtual Machineおよびコンパイラの使用例。入力として、XMLファイルおよびXPath式を取ります。評価されたXPath式の結果を生成します。