RE: Schema Design: Composition vs Subclassing

Schematron provides a way to extract constraints from appinfo and apply
them. That's convenient in that you can co-locate the constraint with the
thing that's being constrained. 

Co-location doesn't help with the problem of having multiple sets of
separate constraints, but a clever xsl programmer can figure out how to put
selection attributes on the appinfo instances and filter accordingly.

FWIW, the fact that a Schematron constraint is co-located doesn't reduce the
amount you have to express in the constraint itself - the constraint doesn't
know where it was extracted from, so it's location in the schema has no
bearing on the scope  of the rule. You have to state that explicitly.

We toyed with the prospect of putting the constraints in appinfo and decided
to store them separately, mainly for configuration management purposes. We
wanted to be able to change the constraints (or add new ones) without
rev'ing the rest of the definition. With co-located constraints, the user
can't tell which part of the xsd has changed.

Mark  


----------------------------------------------------------------------------
----
 
Mark Feblowitz                                   [t] 617.715.7231
Frictionless Commerce Incorporated     [f] 617.495.0188 
XML Architect                                     [e]
mfeblowitz@frictionless.com
400 Technology Square, 9th Floor 
Cambridge, MA 02139 
www.frictionless.com  
 

 -----Original Message-----
From: 	John Utz [mailto:utz@singingfish.com] 
Sent:	Wednesday, April 17, 2002 11:41 AM
To:	Paul Kiel
Cc:	xmlschema-dev@w3.org; Henry S. Thompson
Subject:	Re: Schema Design: Composition vs Subclassing

Hi;

please forgive my impertinent interruption......

On Tue, 16 Apr 2002, Paul Kiel wrote:

> 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.

the fact that one doesnt seem to exist for what is a very reasonable
problem has increased my dissatisfaction with pure XMLSchema to a crucial
point.

this isnt the only 'cant do that in XMLSchema' that i have experienced
lately. my own cross to bear has been co-occurence constraints.

> I think we are just plain stuck with creating a different Person for
> each transaction.

bleah! it's a solution of sorts, and it's probably fine if it's going to
only be 3 different Persons. but what if it's 15? or 50?

> 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.

Would using Schematron payload in the appinfo field to define the
derived PersonTypes make the model simpler and more directly
extensible? sorry that it's such an off the wall suggestion, but it seems
like a good question to ask at this point since the pure XMLSchema
suggestions seem to be getting pretty contrived.

i dont have an explicit recipe of *how* you would describe it in
schematron.i have only paid attention to this thread from the perspective
of the large schema design and implementation issues, so i dont know your
specific needs.

i simply tossed this out because it solved my co-occurance constraint
problem, and the more i think of it, the more convince i am that it's  a
general, albeit hacky, solution.

(thanks go to eddie and roger and jeni and probably others that i am
unaware of for pointing out this solution in the first place)

> 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 13:10:15 UTC