W3C home > Mailing lists > Public > xmlschema-dev@w3.org > April 2002

Re: Schema Design: Composition vs Subclassing

From: Paul Kiel <paul@hr-xml.org>
Date: Tue, 16 Apr 2002 14:49:11 -0400 (EDT)
Message-ID: <004c01c1e577$aa9e6220$6501a8c0@pkiel2>
To: <xmlschema-dev@w3.org>
Thanks Jeni and Mark,

You both have hit the crux of the matter exactly.  I guess I was hoping for
that magical "other option" that would meet our needs and remain simple.  I
think we are just plain stuck with creating a different Person for each
transaction. This won't prevent me from creating a model for reference and
consistency, however.  One that is seperate from transactional schemas.
That "pain" as Mark puts it is worth a bit of effort.  The derivation by
restriction is not an option, derivation by extension (with external
constraints) is a good approach but one that would take some convincing, and
using abstract / redefine would be good job security for the schema editors
like me but not so for domain experts who are newer to xml schema.

Thanks,
Paul Kiel




----- Original Message -----
From: "Jeni Tennison" <jeni@jenitennison.com>
To: "Paul Kiel" <paul@hr-xml.org>
Cc: <xmlschema-dev@w3.org>
Sent: Tuesday, April 16, 2002 12:00 PM
Subject: Re: Schema Design: Composition vs Subclassing


> Hi Paul,
>
> > I have a question about the effect of this best practice. It is
> > regarding context-specific use of components. Let's take the element
> > <Person> in a human resources context. (BTW - <Person> is too broad
> > a concept to actually encode, this is only for discussion). We may
> > want to use a <Person> in many contexts, where some of its
> > components are required in one and not in another. Let's say we have
> > two transactions of Person below (and that all children are stand
> > alone components):
> >
> > Transaction 1:
> > <Person>
> >      <Name/><!-- required -->
> >      <Skills/><!-- required -->
> >      <Height/><!-- required -->
> >      <Weight/><!-- required -->
> > </Person>
> > In this transaction, we need all the data about this person to do
> > the transaction.
> >
> > Transaction 2:
> > <Person>
> >      <Name/><!-- required -->
> >      <Skills/><!-- optional -->
> > </Person>
> > In this transaction, we only need a name of the person and the
> > skills are optional. The Height and Weight have no meaning in this
> > context and can't occur.
>
> None of the methods that you suggested seem particularly good to me.
> In the example above, you have one thing that stays the same (<Person>
> always has a <Name> element child), and two things that change
> (whether <Skills> is required or optional, and whether the <Person>
> includes a <Height> and <Weight>).
>
> If you can take advantage of treating all Person elements in the same
> way when it comes to their Name (i.e. that you can get some code reuse
> out of it), I'd make a general PersonType that included a <Name>
> element:
>
> <xs:complexType name="PersonType" abstract="yes">
>   <xs:sequence>
>     <xs:element name="Name" type="xs:string" />
>   </xs:sequence>
> </xs:complexType>
>
> I'd then create types that extend this base type. For Transaction 1:
>
> <xs:complexType name="Transaction1PersonType">
>   <xs:extension base="PersonType">
>     <xs:sequence>
>       <xs:element name="Skills" type="SkillsType" />
>       <xs:element name="Height" type="xs:decimal" />
>       <xs:element name="Weight" type="xs:decimal" />
>     </xs:sequence>
>   </xs:extension>
> </xs:complexType>
>
> <xs:complexType name="Transaction2PersonType">
>   <xs:extension base="PersonType">
>     <xs:sequence>
>       <xs:element name="Skills" type="SkillsType" minOccurs="0" />
>     </xs:sequence>
>   </xs:extension>
> </xs:complexType>
>
> If you can't take advantage of the fact that the Person elements in
> Transaction1 and Transaction2 are similar (i.e. for some reason you
> can't share code between them) then you could design through
> composition instead. This time the shared components should go into
> groups:
>
> <xs:group name="NameGroup">
>   <xs:sequence>
>     <xs:element name="Name" type="xs:string" />
>   </xs:sequence>
> </xs:group>
>
> <xs:group name="SkillsGroup">
>   <xs:sequence>
>     <xs:element name="Skills" type="SkillsType" />
>   </xs:sequence>
> </xs:group>
>
> <xs:group name="HeightAndWeightGroup">
>   <xs:sequence>
>     <xs:element name="Height" type="xs:decimal" />
>     <xs:element name="Weight" type="xs:decimal" />
>   </xs:sequence>
> </xs:group>
>
> Then you could have two (possibly anonymous) types that bring those
> groups together as required:
>
> <xs:complexType name="Transaction1PersonType">
>   <xs:sequence>
>     <xs:group ref="NameGroup" />
>     <xs:group ref="SkillsGroup" />
>     <xs:group ref="HeightAndWeightGroup" />
>   </xs:sequence>
> </xs:complexType>
>
> <xs:complexType name="Transaction2PersonType">
>   <xs:sequence>
>     <xs:group ref="NameGroup" />
>     <xs:group ref="SkillsGroup" minOccurs="0" />
>   </xs:sequence>
> </xs:complexType>
>
> A third possibility would be to have an abstract version of the
> PersonType that includes a group with nothing in it as a placeholder:
>
> <xs:complexType name="PersonType" abstract="yes">
>   <xs:sequence>
>     <xs:element name="Name" type="xs:string" />
>     <xs:group ref="PersonGroup" />
>   </xs:sequence>
> </xs:complexType>
>
> <xs:group name="PersonGroup">
>   <xs:sequence />
> </xs:group>
>
> Then, in the schema for Transaction 1, you can redefine the
> PersonGroup group to add the required elements:
>
> <xs:redefine href="baseSchema">
>   <xs:group name="PersonGroup">
>     <xs:sequence>
>       <xs:group ref="PersonGroup" />
>       <xs:element name="Skills" type="SkillsType" />
>       <xs:element name="Height" type="xs:decimal" />
>       <xs:element name="Weight" type="xs:decimal" />
>     </xs:sequence>
>   </xs:group>
> </xs:redefine>
>
> and similarly in the schema for Transaction 2:
>
> <xs:redefine href="baseSchema">
>   <xs:group name="PersonGroup">
>     <xs:sequence>
>       <xs:group ref="PersonGroup" />
>       <xs:element name="Skills" type="SkillsType" minOccurs="0" />
>     </xs:sequence>
>   </xs:group>
> </xs:redefine>
>
> Personally, I think I'd favour 1, but I'm in the process of being
> persuaded towards composition, so I reserve the right to change my
> mind.
>
> Cheers,
>
> Jeni
>
> ---
> Jeni Tennison
> http://www.jenitennison.com/
>
>
>
Received on Wednesday, 17 April 2002 05:08:20 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 11 January 2011 00:14:30 GMT