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

前
 
次
 

29 XML Class Generator for C++の使用

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

XML C++ Class Generatorの入手方法

XML C++ Class Generatorは、Oracle Databaseに付属しています。

XML C++ Class Generatorの使用

XML C++ Class Generatorは、XML DTDまたはXML Schemaからソース・ファイルを作成します。XML C++ Class GeneratorはDocument Type Definition(DTD)またはXML Schemaを使用し、定義された各要素用のクラスを生成します。これらのクラスをC++プログラムで使用し、DTDに準拠するXML文書を作成します。

これは、アプリケーションがDTDまたはXML Schemaに従って、またはXML文書を構成するWebフォームのバックエンドとして、他のアプリケーションにXMLメッセージを送信する必要がある場合に有効です。C++アプリケーションは、これらのクラスを使用して、入力用DTDに準拠するXML文書を構成、検証および出力できます。

XML C++ Class Generatorは、Oracle XML Parser for C++と連携して機能します。XML Parser for C++は、入力用DTDを解析し、解析済文書をClass Generatorに渡します。

外部DTDの解析

XML C++ Class Generatorは、完全なドキュメント(ダミー・ドキュメント)をリクエストすることなく、直接外部DTDを解析することもできます。これには、Oracle XML Parser for C++ルーチンのxmlparseDTD()を使用します。

提供されているコマンドライン・プログラムxmlcgには、オプション「-d」があります。これは、外部DTDの解析に使用されます。

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

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

XML C++ Class Generatorコマンドライン・ユーティリティの使用

単独のClass Generatorは、bin/xmlcgをコールすることによって、実行可能ファイルとしてコールできます。

  1. C++ Class Generatorは、コマンドラインに次のように入力して実行できます。

    xmlcg [options] input_file
    

    表29-1に、このユーティリティのオプションを示します。

    表29-1 C++ Class Generatorのオプション

    オプション 意味

    -d name

    入力は外部DTDまたはDTDファイルです。name.cppおよびname.hを生成します。

    -o directory

    生成されたファイル用の出力ディレクトリ: デフォルトは、現在のディレクトリです。

    -e encoding

    デフォルトの入力ファイルのエンコーディングです。

    -h

    使用方法のヘルプを表示します。

    -v

    XML C++ Class Generatorのバージョンのバリデータ・オプションを表示します。

    -s name

    指定された名前を持つXML Schemaファイルを入力します。name.cppおよびname.hを生成します。


    input_file名は、<!DOCTYPE>を定義する解析済XML文書、解析済DTDまたはXML Schema文書の名前です。XML文書には、DTDが対応付けられている必要があります。

    XML C++ Class GeneratorへのDTDの入力は、DTDを含むXML文書、または外部DTDです。文書本体自体は無視され、DTDのみが使用されますが、文書はDTDに準拠している必要があります。

  2. オプションが無効な場合、または入力が指定されない場合は、前述した情報を含む使用メッセージが出力されます。

  3. 2つのソース・ファイル、name.hヘッダー・ファイルおよびC++ファイル、name.cppが出力されます。これらのファイルには、DTDファイルと同じ名前が付けられます。

  4. 出力ファイルは、通常、XML文書の生成に使用されます。

各クラス(要素)にコンストラクタが提供されているため、次の2つの方法でオブジェクトを作成できます。

  • まず空のオブジェクトを作成し、後で子またはデータを追加します。

  • 最初からすべての子または初期データを含むオブジェクトを作成します。

#PCDATA(および混合)要素用に提供されているメソッドを使用すると、データを設定したり、適切な場合は、要素の属性を設定することができます。

XML C++ Class Generatorへの入力

入力は、DTDを含むXML文書です。文書本体自体は無視され、DTDのみが使用されますが、ダミー・ドキュメントはDTDに準拠している必要があります。基礎となるXMLパーサーは、文書および関連する外部エンティティのファイル名を受け入れるのみです。

XML C++ Class Generatorの使用例

表29-2に、XML C++ Class Generatorのデモ・ファイルを示します。

表29-2 XML C++ Class Generatorファイル

ファイル名 説明

CG.cpp

サンプル・プログラム

CG.xml

DTDおよびダミー・ドキュメントを含むXMLファイル

CG.dtd

sample.xmlが参照するDTDファイル

Make.bat(Windows)

Makefile(UNIX)

クラスを生成し、サンプル・プログラムを構築する、バッチ・ファイル(Windowsの場合)またはMakeファイル(UNIXの場合)。

README

前述のファイルの説明を含むREADMEファイル


Make.batバッチ・ファイル(Windowsの場合)またはMakefile(UNIXの場合)では、次の操作が実行できます。

  • sample.xmlに基づいて、クラスをSample.hおよびSample.cppに生成します。

  • (Sample.hを使用して)プログラムsample.cppをコンパイルし、サンプル・オブジェクトとともに...\bin(または.../bin)ディレクトリにあるCG.exeという実行可能ファイルにリンクします。

XML C++ Class Generatorの例1: XML - Class Generatorの入力ファイルsample.xml

CG.xmlというXMLファイルは、XML C++ Class Generatorを入力します。これは、CG.dtdというDTDファイルを参照します。

<?xml version="1.0"?>
<!DOCTYPE Sample SYSTEM "CG.dtd">
  <Sample>
    <B>Be!</B>
    <D attr="value"></D>
    <E>
      <F>Formula1</F>
      <F>Formula2</F>
    </E>
  </Sample>

XML C++ Class Generatorの例2: DTD - Class Generatorの入力ファイルsample.dtd

DTDファイルsample.dtdは、XMLファイルsample.xmlによって参照されます。sample.xmlは、XML C++ Class Generatorを入力します。

<!ELEMENT Sample (A | (B, (C | (D, E))) | F)>
<!ELEMENT A (#PCDATA)>
<!ELEMENT B (#PCDATA | F)*>
<!ELEMENT C (#PCDATA)>
<!ELEMENT D (#PCDATA)>
<!ATTLIST D attr CDATA #REQUIRED>
<!ELEMENT E (F, F)>
<!ELEMENT F (#PCDATA)>

XML C++ Class Generatorの例3: sample.cppサンプル・プログラム

サンプル・プログラムsample.cppは、次のとおり実行します。

  1. XMLパーサーを初期化します。

  2. DTDを含むファイルのダミー・ドキュメント部分以外を解析することによって、DTDをロードします。

  3. 生成されたクラスを使用して複数のオブジェクトを作成します。

  4. 生成されたクラスがDTDに一致するかどうかを検証する、検証関数をコールします。

  5. 作成されたドキュメントをSample.xmlに書き込みます。

//////////////////////////////////////////////////////////////////////////////
// NAME        CG.cpp
// DESCRIPTION Demonstration program for C++ class generator usage
//////////////////////////////////////////////////////////////////////////////

#ifndef ORAXMLDOM_ORACLE
# include <oraxmldom.h>
#endif

#include <fstream.h>

#include "Sample.h"

#define DTD_DOCUMENT "CG.xml"
#define OUT_DOCUMENT Sample.xml"

int main()
{
    XMLParser parser;
    Document *doc;
    Sample   *samp;
    B        *b;
    D        *d;
    E        *e;
    F        *f1, *f2;
    fstream  *out;
    ub4       flags = XML_FLAG_VALIDATE;
    uword     ecode;

    // Initialize XML parser
    cout << "Initializing XML parser...\n";
    if (ecode = parser.xmlinit())
    {
        cout << "Failed to initialize parser, code " << ecode << "\n";
        return 1;
    }

    // Parse the document containing a DTD; parsing just a DTD is not
    // possible yet, so the file must contain a valid document (which
    // is parsed but we're ignoring).
    cout << "Loading DTD from " << DTD_DOCUMENT << "...\n";
    if (ecode = parser.xmlparse((oratext *) DTD_DOCUMENT, (oratext *)0, flags))
    {
        cout << "Failed to parse DTD document " << DTD_DOCUMENT <<
        ", code " << ecode << "\n";
        return 2;
    }

    // Fetch dummy document
    cout << "Fetching dummy document...\n";
    doc = parser.getDocument();

    // Create the constituent parts of a Sample
    cout << "Creating components...\n";
    b = new B(doc, (String) "Be there or be square");
    d = new D(doc, (String) "Dit dah");
    d->setattr((String) "attribute value");
    f1 = new F(doc, (String) "Formula1");
    f2 = new F(doc, (String) "Formula2");
    e = new E(doc, f1, f2);

    // Create the Sample
    cout << "Creating top-level element...\n";
    samp = new Sample(doc, b, d, e);

    // Validate the construct
    cout << "Validating...\n";
    if (ecode = parser.validate(samp))
    {
     cout << "Validation failed, code " << ecode << "\n";
     return 3;
    }

    // Write out doc
    cout << "Writing document to " << OUT_DOCUMENT << "\n";
    if (!(out = new fstream(OUT_DOCUMENT, ios::out)))
    {
      cout << "Failed to open output stream\n";
      return 4;
    }
    samp->print(out, 0);
    out->close();

    // Everything's OK
    cout << "Success.\n";

    // Shut down
    parser.xmlterm();
    return 0;
}

// end of CG.cpp