この章の内容は次のとおりです。
XML C++ Class Generatorはデータベースに付属し、OTNサイト(http://www.oracle.com/technology/tech/xml
)からダウンロードして入手することもできます。
XML C++ Class Generatorは、XML DTDまたはXML Schemaからソース・ファイルを作成します。このClass GeneratorはDocument Type Definition(DTD)またはXML Schemaを使用し、定義された各要素用のクラスを生成します。これらのクラスをC++プログラムで使用し、DTDに準拠するXML文書を作成します。
これは、アプリケーションがDTDまたはXML Schemaに従って、またはXML文書を構成するWebフォームのバックエンドとして、他のアプリケーションにXMLメッセージを送信する必要がある場合に有効です。C++アプリケーションは、これらのクラスを使用して、入力用DTDに準拠するXML文書を構成、検証および出力できます。
このClass Generatorは、Oracle XML Parser for C++と連携して機能します。Oracle XML Parser for C++は、入力用DTDを解析し、解析済文書をClass Generatorに渡します。
単独のClass Generatorは、bin/xmlcg
をコールすることによって、実行可能ファイルとしてコールできます。
C++のコマンドラインClass Generatorbin/xmlcg
を次の方法で起動します。
xmlcg [options] input_file
表23-1に、オプションを示します。
表23-1 Class Generatorのオプション
オプション | 意味 |
---|---|
|
入力は外部DTDまたはDTDファイルです。 |
|
生成されたファイル用の出力ディレクトリ: デフォルトは、現在のディレクトリです。 |
|
デフォルトの入力ファイルのエンコーディングです。 |
|
使用方法のヘルプを表示します。 |
-v |
XML C++ Class Generatorのバージョンのバリデータ・オプションを表示します。 |
-s name |
指定された名前を持つXML Schemaファイルを入力します。 |
input_file
名は、<!DOCTYPE>を定義する解析済XML文書、解析済DTDまたはXML Schema文書の名前です。XML文書には、DTDが対応付けられている必要があります。
XML C++ Class GeneratorへのDTDの入力は、DTDを含むXML文書、または外部DTDです。文書本体自体は無視され、DTDのみが使用されますが、文書はDTDに準拠している必要があります。
オプションが無効な場合、または入力が指定されない場合は、前述した情報を含む使用メッセージが出力されます。
2つのソース・ファイル、name.hヘッダー・ファイルおよびC++ファイル、name.cppが出力されます。これらのファイルには、DTDファイルと同じ名前が付けられます。
出力ファイルは、通常、XML文書の生成に使用されます。
各クラス(要素)にコンストラクタが提供されているため、次の2つの方法でオブジェクトを作成できます。
まず空のオブジェクトを作成し、後で子またはデータを追加します。
最初からすべての子または初期データを含むオブジェクトを作成します。
#PCDATA
(および混合)要素用に提供されているメソッドを使用すると、データを設定したり、適切な場合は、要素の属性を設定することができます。
表23-2に、XML C++ Class Generatorのデモ・ファイルを示します。
表23-2 XML C++ Class Generatorファイル
ファイル名 | 説明 |
---|---|
|
サンプル・プログラム |
|
DTDおよびダミー・ドキュメントを含むXMLファイル |
|
sample.xmlが参照するDTDファイル |
|
クラスを生成し、サンプル・プログラムを構築する、バッチ・ファイル(Windowsの場合)またはMakeファイル(UNIXの場合) |
README |
前述のファイルの説明を含むREADMEファイル |
make.bat
バッチ・ファイル(Windows NTの場合)またはMakefile
(UNIXの場合)では、次の操作を実行できます。
sample.xml
に基づいて、クラスをSample.hおよびSample.cppに生成します。
(Sample.h
を使用して)プログラムCG.cpp
をコンパイルし、サンプル・オブジェクトとともに...\bin
(または.../bin
)ディレクトリにあるCG.exe
という実行可能ファイルにリンクします。
XMLファイルCG.xml
は、XML C++ Class Generatorを入力します。これは、DTDファイルCG.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>
DTDファイルCG.dtd
は、XMLファイルCG.xml
によって参照されます。CG.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)>
CGサンプル・プログラムCG.cpp
は、次のとおり実行します。
XMLパーサーを初期化します。
DTDを含むファイルのダミー・ドキュメント部分以外を解析することによって、DTDをロードします。
生成されたクラスを使用して複数のオブジェクトを作成します。
生成されたクラスがDTDに一致するかどうかを検証する、検証関数をコールします。
作成されたドキュメントを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