This chapter explains how to use the Extensible Markup Language (XML) class generator for C++.
Topics:
The XML C++ class generator is provided with Oracle Database.
The XML C++ class generator creates source files from an XML document type definition (DTD) or XML Schema. The class generator takes the DTD or the XML Schema, and generates classes for each defined element. Those classes are then used in a C++ program to construct XML documents conforming to the DTD.
This is useful when an application wants to send an XML message to another application based on an agreed-upon DTD or XML Schema, or as the back end of a Web form to construct an XML document. Using these classes, C++ applications can construct, validate, and print XML documents that comply with the input.
The class generator works with the Oracle XML parser for C++, which parses the input and passes the parsed document to the class generator.
The XML C++ class generator can also parse an external DTD directly without requiring a complete (dummy) document by using the Oracle XML parser for C++ routine xmlparsedtd()
.
The provided command-line program xmlcg
has a -d
option that is used to parse external DTDs.
The standalone class generator can be called as an executable by invoking bin/xmlcg
.
Constructors are provided for each class (element) that allow an object to be created in these ways:
Initially empty, then adding the children or data after the initial creation
Created with the initial full set of children or initial data
A method is provided for #PCDATA
(and Mixed) elements to set the data and, when appropriate, set an element's attributes.
The input is an XML document containing a DTD. The document body itself is ignored; only the DTD is relevant, though the dummy document must conform to the DTD. The underlying XML parser accepts only file names for the document and associated external entities.
Table 31-2 lists the demo XML C++ class generator files:
Table 31-2 XML C++ Class Generator Files
File Name | Description |
---|---|
|
Sample program |
|
XML file contains DTD and dummy document |
|
DTD file referenced by |
|
Batch file (on Windows) or Make file (on UNIX) to generate classes and build the sample programs. |
README |
A readme file with these instructions |
The make.bat
batch file (on Windows) or Makefile
(on UNIX) do this:
Generate classes based on CG.xml
into Sample.h
and Sample.cpp
Compile the program CG.cpp
(using Sample.h
), and link this with the Sample object into an executable named CG.exe
in the...\bin
(or .../bin
) directory.
This XML file, CG.xml
, inputs XML C++ class generator. It references the DTD file, 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>
This DTD file, CG.dtd
is referenced by the XML file CG.xml
. CG.xml
inputs 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)>
The CG sample program, CG.cpp
, does this:
Initializes the XML parser.
Loads the DTD (by parsing the DTD-containing file—the dummy document part is ignored).
Creates some objects using the generated classes.
Invokes the validation function which verifies that the constructed classes match the DTD.
Writes the constructed document to 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