[xsd-users] Using XSD for partial XML Data Binding in a large application

Boris Kolpackov boris at codesynthesis.com
Fri Mar 3 07:49:57 EST 2006


Marco,

Marco Fischer <marco.fischer at chipvision.com> writes:

> For example, the application wishes to access an element X associated
> with an element A.
>
>  ____________                  ____________
> |      A     |                |      X     |
> |____________|                |____________|
> |            |          ref   |            |
> |            |--------------->|            |
> |____________|                |____________|
>
>
> If both elements are modelled in the data binding, the generated class
> for A provides an appropriate member function, something like
>
> X A::ref().
>
> If X is not part of the data binding, then of course there's no such
> member function. There could also be needs to have other member
> functions in the interface of A, not modelled in the data binding.

This is a hard problem. There are currently two approaches that we are
evaluating. Suppose you have the following schema:

<complexType name="A">
  ...
</complexType>

<complexType name="B">
  <sequence>
    <element name="a" type="A"/>
  </sequence>
</complexType>

And you want to extend A. As you correctly pointed above, it is not
enough to merely derive from A and using that type when constructing
the tree. When you call b.a () you get A, not your derived class. The
only way to get to the actual type is by casting it:

B& b (...);
MyA& (static_cast<A&> (b.a ()));

The first solution would allow you to inherit the generated class from
your own type, e.g.,:

<complexType name="A" native-base="AInterface">
  ...
</complexType>

(or doing this using a command line option).

You may still need to create another type and derive it from A if
you want to use the data from the binding. For example:

struct AInterface
{
  virtual void print () = 0;
};

class A: public AInterface, ... // generated class
{

};

class AImpl: public A
{
  virtual void print ()
  {
    // use data from A
  }
};

Now you will be able to write something like this:

B& b (...);
A& (b.a ());
a.print ();

The main disadvantage of this approach is that it is quite verbose. The
second solution is to generate class templates for schema types instead
of normal classes:

template<...>
class A
{
  ...
};

template <typename A>
class B
{
  A& a ();
  ...
};

Now, in your code, you can do something like this:

class MyA: A<...>
{
  void print ()
  {
    // use data from A
  }
};


typedef B<MyA> MyB;


MyB& b (...);
MyA& (b.a ());
a.print ();

The problem with this approach is that it is a whole new mapping ;-).
You can also read some more on this topic in these threads:

http://codesynthesis.com/pipermail/xsd-users/2005-September/000024.html
http://codesynthesis.com/pipermail/xsd-users/2006-February/000219.html

We probably could implement the first solution after 2.0.0 is out.

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/20060303/854010ae/attachment.pgp


More information about the xsd-users mailing list