[xsd-users] XSD serialize to and from wstring
Boris Kolpackov
boris at codesynthesis.com
Wed Oct 15 14:07:20 EDT 2008
Hi George,
George Vassilakes <george at sbdev.net> writes:
> When I changed to using wchar_t (option --char-type wchar_t) I expected
> that the code would generate serialization functions using
> wisstringstream and wostringstream.
Because an XML document can be in a variety of encodings with
different character sizes (e.g., UTF-8, UTF-16, and UTF-32) the
document stream is always treated as a byte sequence. This is
why, for example, you can open a UTF-32 XML file with
std::ifstream and parse it with one of the parsing functions.
Similarly, you can write the object model to std::ofstream
in UTF-32 using one of the serialization functions.
One way to parse std::wstring is to use the MemBufInputSource
class provided by Xerces-C++. The following code fragments
assume that you are using the latest version of XSD (3.2.0)
and that root_t is the root type and root() is the name of
the parsing/serialization functions:
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
using namespace xercesc;
std::wstring s = ...
std::auto_ptr<root_t> r;
XMLPlatformUtils::Initialize ();
{
MemBufInputSource is (reinterpret_cast<const XMLByte*> (s.c_str ()),
s.size () * sizeof (wchar_t));
// If the XML document in s does not specify the encoding in
// XML declaration, then you may also need to set the encoding:
//
// if (sizeof (wchar_t) == 2)
// {
// is.setEncoding (XMLUni::fgUTF16EncodingString); // UTF-16
// }
// else
// {
// is.setEncoding (XMLUni::fgUCS4EncodingString); // UTF-32
// }
r = root (is);
}
XMLPlatformUtils::Terminate ();
Similarly, to serialize to std::wstring one can use MemBufFormatTarget:
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
using namespace xercesc;
std::auto_ptr<root_t> r = ...;
std::wstring s;
XMLPlatformUtils::Initialize ();
{
MemBufFormatTarget ft (512); // First argument is the initial buf size.
xml_schema::namespace_infomap map;
// Fill in the map.
root (ft, *r, map, (sizeof (wchar_t) == 2 ? "UTF-16" : "UTF-32"));
s.assign (reinterpret_cast<const wchar_t*> (ft.getRawBuffer ()),
ft.getLen () / sizeof (wchar_t));
}
XMLPlatformUtils::Terminate ();
It is also possible to do the same via the std::istream/std::ostream
interfaces. For that you will need to implement your own stream
buffers that read/write directly from/to std::wstring as a byte
sequence. The zc_istream implementation in libxsd/xsd/cxx/zc_istream.*
can help get you started if you are interested in this approach.
Boris
More information about the xsd-users
mailing list