XML Streams Module User’s Guide : Chapter 4 Enhanced Streams : Example
Example
This example uses a simple object named book that holds an author name and a book title:
 
class book
{
public:
book ();
book (const RWCString& title, const RWCString& author);
private:
RWCString title_;
RWCString author_;
};
As described in the example in Chapter 3, you must add macros to the header and implementation files to prepare the object for serialization.
To the header file, add the macro RW_DECLARE_VIRTUAL_STREAM_FNS(), which defines the streamContents() member function:
 
class book
{
RW_DECLARE_VIRTUAL_STREAM_FNS(book)
 
public:
book ();
book (const RWCString& title, const RWCString& author);
 
private:
RWCString title_;
RWCString author_;
};
Add to the header file:
// Add serialization support
RW_DECLARE_STREAMABLE_AS_SELF(book)
RW_DECLARE_STREAMABLE_POINTER(book)
 
To the implementation file, first add macros that define insertion and extraction operators for the class members:
 
// Define how book will be serialized
RW_BEGIN_STREAM_CONTENTS(book)
RW_STREAM_ATTR_MEMBER(title,title_)
RW_STREAM_ATTR_MEMBER(author,author_)
RW_END_STREAM_CONTENTS
Then add macros that allow the book object itself to be serialized as a pointer reference:
 
// Allow a reference to a book to be serialized
RW_DEFINE_STREAMABLE_POINTER(book)
RW_DEFINE_STREAMABLE_AS_SELF(book)
Now you are ready to look at the example itself.
Example Discussion
This section explains the main() function for the example. The explanation is broken into three parts:
creating a book object and serializing it to a file using an enhanced XML output stream
reading the file back in and restoring the book object using an enhanced XML input stream
printing out both the basic XML streams data for the book object and its more readable, enhanced XML stream version
For the complete example, see:
buildspace\examples\xmlstreams\xsltTransform\enhanced.cpp
Serializing the book Object to a File
First create a book object and serialize it out to a file. Because the XML format generated by XML streams is difficult to read, transform the output stream to a more easily-readable format.
 
int main()
{
using std::ofstream; //1
using std::ifstream;
using std::cout;
using std::endl;
 
book book1("To Love and Be Wise","Josephine Tey"); //2
book book2;
 
{
ofstream fout("book.xml"); //3
 
RWObjectOutputStream out = //4
RWEnhancedXmlObjectOutputStreamImp::make(fout);
out << book1; //5
 
}
//1 Indicates that certain variables refer to their counterparts in the STD namespace.
//2 Creates two book objects, one with data, one to hold the data when you restore the object later.
//3 Creates an ofstream for writing character data to a file.
//4 Sets up an enhanced XML output stream that includes support for a transformation.
//5 Serializes the book object to a file.
Restoring the book Object
At this point you have written the book object XML data to the file book.xml. Next restore the object, which involves:
reading in the file book.xml
restoring the object as book2
 
{
ifstream fin("book.xml"); //1
 
RWObjectInputStream in = //2
RWEnhancedXmlObjectInputStreamImp::make(fin);
in >> book2; //3
}
//1 Creates an ifstream for reading in the object data.
//2 Sets up an enhanced XML input stream.
//3 Restores the book object as the book2 instance create earlier.
Examining the XML Output
Finally, the example writes to standard out two forms of the serialized object. You’ll also use the rwInsertWithName() global method in order to provide an instance name for the book object.
 
{
RWObjectOutputStream out = //1
RWEnhancedXmlObjectOutputStreamImp::make(cout);
out << rwInsertWithName("book2",book2); //2
}
cout << endl;
{
RWObjectOutputStream out = //3
RWXmlObjectOutputStreamImp::make(cout);
out << rwInsertWithName("book2",book2); //4
}
return 0;
}
//1 Sets up an enhanced XML output stream.
//2 Streams the enhanced version of the book2 object to standard out.
//3 Sets up an XML output stream with no transformation support.
//4 Streams the standard XML streams version of the book2 object to standard out.
Here is the resulting output:
In enhanced XML stream format:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book2
xmlns:rw="http://www.roguewave.com/xmlstream" rw:class="book"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
xsi:type="rw:nested_object">
<title xsi:type="xsd:string">To Love and Be Wise</title>
<author xsi:type="xsd:string">Josephine Tey</author>
</book2>
In ordinary XML stream format:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rw:nested_object rw:name="book2" rw:class="book"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:rw="http://www.roguewave.com/xmlstream">
<rw:member rw:name="title" xsi:type="xsd:string">To Love and Be
Wise</rw:member>
<rw:member rw:name="author" xsi:type="xsd:string">Josephine
Tey</rw:member></rw:nested_object>
If you need to control the format of the data within the XML stream, the streams classes have a make() function that takes a pointer reference to an std::ios object. The constructor for the XML stream fills this pointer with the address of a formatting object for the underlying character stream. Here is an example for the class RWEnhancedXmlObjectOutputStreamImp.
 
std::ios* formatter; // uninitialized pointer
RWObjectOutputStream xostr =
RWEnhancedXMLObjectOutputStreamImp::make(
outfile,script,formatter);
formatter->precision(15); // manipulate data format
The following classes contain a make() function that supports a formatting object:
RWXmlObjectInputStreamImp
RWXmlObjectOutputStreamImp
RWEnhancedXmlObjectInputStreamImp
RWEnhancedXmlObjectOutputStreamImp
RWTTransformObjectInputStreamImp
RWTTransformObjectOutputStreamImp