[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