この章では、Extensible Markup Language (XML) Class Generator for C++の使用方法について説明します。
内容は次のとおりです。
XML C++ Class Generatorでは、XML Document Type Definition (DTD)またはXML Schemaからソース・ファイルを作成します。Class Generatorは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に渡します。
XML C++ Class Generatorは、完全なドキュメント(ダミー・ドキュメント)をリクエストすることなく、直接外部DTDを解析することもできます。これには、Oracle XML Parser for C++ルーチンのxmlparseDTD()
を使用します。
提供されているコマンドライン・プログラムxmlcg
には、-d
オプションがあります。これは、外部DTDの解析に使用されます。
単独のClass Generatorは、bin/xmlcg
をコールすることによって、実行可能ファイルとしてコールできます。
各クラス(要素)にコンストラクタが提供されているため、次の方法でオブジェクトを作成できます。
まず空のオブジェクトを作成し、後で子またはデータを追加します。
最初からすべての子または初期データを含むオブジェクトを作成します。
#PCDATA
(および混合)要素用に提供されているメソッドを使用すると、データを設定したり、適切な場合は、要素の属性を設定することができます。
表31-2に、XML C++ Class Generatorのデモ・ファイルを示します。
表31-2 XML C++ Class Generatorファイル
ファイル名 | 説明 |
---|---|
|
サンプル・プログラム |
|
DTDおよびダミー・ドキュメントを含むXMLファイル |
|
|
|
クラスを生成し、サンプル・プログラムを構築する、バッチ・ファイル(Windowsの場合)またはMakeファイル(UNIXの場合)。 |
README |
前述のファイルの説明を含むREADMEファイル |
Make.bat
バッチ・ファイル(Windowsの場合)またはMakefile
(UNIXの場合)では、次の操作が実行できます。
CG.xml
に基づいて、クラスをSample.h
およびSample.cpp
に生成します。
(Sample.h
を使用して)プログラムsample.cpp
をコンパイルし、サンプル・オブジェクトとともに...\bin
(または.../bin
)ディレクトリにあるCG.exe
という実行可能ファイルにリンクします。
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>
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)>
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