[xsd-users] xs:choice representation in C++

Gershanovich, Leonid leonid.gershanovich at 247realmedia.com
Tue Sep 29 00:23:32 EDT 2009


Boris,

> Please see this post for some background on the possible choices when
> mapping xs:choice (pun intended ;-)) to C++:
> http://www.codesynthesis.com/pipermail/xsd-users/2007-March/000863.html

I read above thread and I would like to comment on following (from above thread):
>> It boils down to whether to recreate the schema
>> structure with an "unnatural" access API or to "flatten" the
>> structure and generate an easy to use but sometimes dangerous
>> API. We decided to go with the flat...

I do believe that there are two separate scenarios:
    a. developer is given a schema
    b. developer designs schema as well as C++ code

In first case, I can imagine that, depending on task at hand, developer might either want
flatten representation of xsd data model in his c++ or might want to have schema structure recreated. Thus it might be convenient to have a command line parameter to control that.
However, in second case, I cannot imagine why developer might want to have flatten representation in c++ code, after all, developer 
can always make his schema in such a way that c++ code is simpler.
In other words - in my opinion, schema is yet another way to express data model/structure, and when I, as a developer, elect to
create complicated schema, than I want my c++ data model to mimic that, otherwise I would have created a simpler schema.

>> Note how we had to invent a lot of names that are not really found
>> in the schema -- they are all candidates for name conflicts

True. But, by using nested classes, instead of putting all definitions on a global scope, name conflicts should occur less frequent.
But you are right, some names that do not exist in schema would need to be invented.

But, as <"Compositors" in the C++/Hybrid Mapping > (http://www.codesynthesis.com/projects/xsde/documentation/cxx/hybrid/guide/#4.4)
demonstrates - you have successfully resolved this already, I mean name invention and name conflicts.

>> While this API preserve the structure of the content, the flat API is
>> probably preferable in this case since all one needs is a list
>> of to's, cc's and bcc's.
This is not 100% true. By giving such lists you lose order of appearance in original xml, which might be significant.

> For your original choice example you will get something like this:
>
> enum choice_arm_tag
> {
>   stringEl_tag,
>   intEl_tag
> };
>
> choice_arm_tag
> choice_arm () const;
>
> void
> choice_arm (choice_arm_tag);
>
> // stringEl
> //
> const std::string&
> stringEl () const;
>
> std::string&
> stringEl ();
>
> void
> stringEl (const std::string&);
>
> // intEl
> //
> int
> intEl () const;
>
> int&
> intEl ();
>
> void
> intEl (int);
>
> See Section 4.4, "Compositors" in the C++/Hybrid Mapping Getting Started
> Guide for more information:
>
> http://www.codesynthesis.com/projects/xsde/documentation/cxx/hybrid/guide/#4.4
Such code structure raises few questions:
1. while it is clear that calling "void intEl (int);" should change choice_arm and set int value, what should happen when "int& intEl ();" is called?
2. furthermore, what should happen when "int intEl () const;" is called while choice_arm() is set to stringEl_tag ?

It seems that while such structure seems suitable for data retrieval, it seem to allow setting both choice arms in case when I am
setting up object for later serialization. Which is not ideal. (boost::variant has cleaner interface in that sense).

Also, can you please clarify for me if it is possible to get "Compositors" generated code (nested classes for xs:sequence, xs:choice and xs:all) while using "CodeSynthesis XSD" with "C++/Tree" mode?

> From my superficial look at boost::variant I gather that there are
> two ways to extract the value: the visitor approach (which will be
> way too heavy-weight for most use-cases) and the boost::get function
> which doesn't really offer many advantages over what is possible now.
> It sure is more awkward, thought.

I do agree that using boost::get is very close to what is possible now. But developer would have a choice:
either use boost::get ("light" accessor) or "heavier" solution.
Right now there are no choice.

Also, I just would like to point out that boost::static_visitor is NOT a "visitor pattern" implementation from Gamma & Co book.
It is a much simpler construct that relies on compile time function overloading, rather than run time polymorphism. 
In other words, while it is heavier than boost::get, it is not as heavy as full blown visitor pattern implementations.

Thanks

Leonid




More information about the xsd-users mailing list