[xsd-users] reading and writing non root elements

Boris Kolpackov boris at codesynthesis.com
Thu Nov 23 10:15:12 EST 2006


Hi Greg,

Greg Carter <greg at permedia.ca> writes:


> I wondering what the best approach would be for the following problem.
> I've defined a schema with one root element which is a complex type made
> up of many other complex types.  All the complex types are defined
> globally (no inner anonymous types).  Once the instance document is read
> in to a XSD generated class I wish to then operate on these sub types,
> changing the data, sending it off to other shared libs to do so.  These
> shared libraries can be written in another language.  So I thought the
> easiest thing to do would be to write the data out to an XML string to
> pass it to the other libraries.  Similarly, have the results passed back
> as an XML string that I can then read back into the XSD generated
> class.  It's assumed the developers of the other libraries will have
> access to schema binding tools similar to XSD.
>
> XSD cxx-tree will generate serialization functions for the schema root
> elements.  Is there an easy way to do this for non root elements?
>
> I see that the class constructors can take a Xercesc DOMElement but I'm
> not sure how to get the string into this.
>
> Would I be better off defining separate schemas for any type that I need
> to use in this way (declaring a root element of that type)?

That would be one way to accomplish this. You could define a separate
schema which will include the original schema and define a root element
for each complex type. You can then compile this schema to obtain
necessary parsing and serialization functions.

The only problem with this approach is that you won't get exactly
the same XML in the following situation:

 1. Your schema defines target namespace

 2. Local elements in your schema are unqualified

In this case your fragment XML will have its root element qualified while
the complete XML document has it unqualified, e.g.,

<tns:rootEle xmlns:tns="http://www.blah.com/MySchema">

  <elOne>...</elOne>
  <elTwo>...</elTwo>
  <elThree>...</elThree>

</tns:rootEle>

And the fragment will look like this:

<tns:elOne xmlns:tns="http://www.blah.com/MySchema">...</elOne>

This is because global elements in XML Schema are always qualified.


The other approach uses generated type's constructors and serialization
operators to parse/serialize the type instance into XML. It also requires
some dealing with Xerces-C++.

First, let's consider the parsing case. We are going to use the helper
function that is shown in the Q 2.1 of the Wiki FAQ[1]. The first
step is to parse your XML string to DOM:

#include <sstream>

using namespace xercesc;
namespace xml = xsd::cxx::xml;

XMLPlatformUtils::Initialize ();

{
  std::istringstream is ("<your XML goes here>");
  xml::dom::auto_ptr<DOMDocument> doc (parse (is));

Then we need to get to the root DOMElement which we can pass to the
ElOneType's constructor:

  DOMElement& e (*doc->getDocumentElement ());

  ElOneType el_one (e);

}

XMLPlatformUtils::Terminate ();


The opposite direction is similar: first we create an empty DOM document,
then we use the generated serialization operator to write the contents of
ElOneType to the document's root element, and, finally, we serialize the
DOM document to XML string. Here we are using helper functions defined
in Q 3.1 and 3.2 of the same FAQ:

#include <sstream>

using namespace xercesc;
namespace xml = xsd::cxx::xml;

XMLPlatformUtils::Initialize ();

{
  xml::dom::auto_ptr<DOMDocument> doc (create ("elOne"));

  DOMElement& e (*doc->getDocumentElement ());

  ElOneType el_one = ...

  e << el_one;

  std::ostringstream os ("<your XML goes here>");

  serialize (os, *doc);

  // XML string is in os.str ()
}

XMLPlatformUtils::Terminate ();

This approach does not have the qualification problem described above.


> I can accomplish writing the data out to a string by using the
> --generate-ostream option.

The --generate-ostream options triggers generation of the std::ostream
insertion operators that print the data in the human-readable form, not
in XML. They are usually used for debugging, etc.


[1] http://wiki.codesynthesis.com/Tree/FAQ


hth,
-boris
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 652 bytes
Desc: Digital signature
Url : http://codesynthesis.com/pipermail/xsd-users/attachments/20061123/a1693fc5/attachment.pgp


More information about the xsd-users mailing list