[xsd-users] Customize sequence and optionals

Boris Kolpackov boris at codesynthesis.com
Wed Jan 28 02:30:55 EST 2009


Hi Stefan,

WEBER Stefan <stefan.weber at efgfp.com> writes:

> In my schema, the reason to make some elements optional is mostly for
> convenience of the user writing the XML, such that the user does not
> have to explicitly specify the element in case he wants to use the
> default value anyway. (e.g. for configuration data) 

Just as an aside, elements with default values in XML Schema are
quite a strange construct. You cannot simply ommit an element with
a default value. Rather, you will need to specify an empty element
in order for it to have the default value.

For example:

<element name="test">
  <complexType>
    <sequence>
      <element name="a" type="int" default="123"/>
    </sequence>
  </complexType>
</element>

This is invalid:

<test></test>

This is valid and the value of 'a' is 123:

<test><a></a></test>

So am not sure how convenient elements with default values will be
in your situation.

Attributes, on the other hand, have a more "sane" behavior in that
if an optional attribute with default value is not present, then
the attribute takes the default value. See Appendix A, "Default and
Fixed Values" in the C++/Tree Mapping User Manual for more information.

For an attribute with a default value XSD generates accessor/modifier
functions as if it was required and automatically initializes it to
the default value when it is not present.


> Now I would like to change the optional type such that whenever get()
> would return a NULL pointer, I create an element of the default value
> and return the newly created element.
>  
> In other words, instead of having a
>  
> typedef xsd::cxx::tree::optional<MyType> MyTypeOptional
>  
> I would rather provide a custom MyTypeOptional. Is this possible?

The only way to do this would be to customize the outer type that
contains MyTypeOptional and redefine the typedef's and functions
for elements with default values. For example, you could base
your custom implementation on the generated version and then
do something like this:

class Outer: OuterBase
{
  MyType&
  my ()
  {
    MyTypeOptional& x = OuterBase::my ();
  
    if (x.present ())
      return x.get ();
    else
    {
      // Return default value.
    }
  }
};

If you have a lot of such elements scattered over many types, then 
this may require quite a bit of customization.

 
> A similar thing for the sequences:
>  
> instead of having generated a
>  
> typedef xsd::cxx::tree::sequence<MyType> MyTypeSequence
>  
> I would rather provide a MyTypeSequence myself. The reason I want to do
> that is that I would prefer to have a vector<MyType> as return value
> rather than sequence<MyType> for sequences (because an 3rd party API
> expects a const vector& and providing a custom sequence would save a lot
> of explicit conversions).

Again, you will need to customize the outer type for that. Also note
that std::vector will store MyType by value which may be quite expensive.

Boris




More information about the xsd-users mailing list