OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.


Help: OASIS Mailing Lists Help | MarkMail Help



   Re: DTD/Schemas with repeated structure

[ Lists Home | Date Index | Thread Index ]
  • From: Joe English <jenglish@flightlab.com>
  • To: xml-dev@lists.xml.org
  • Date: Thu, 24 Aug 2000 14:50:57 -0700

Justin Lipton wrote:
> I was wondering if anyone has come across this problem.

Something very close to it, yes...

> We are currently using a DTD that has the following structure.
> <!ELEMENT Mammal (MammalName, MammalType)>
> 	<!ELEMENT MammalName (#PCDATA)>
> 		<!ATTLIST MammalName (latin|common) "common">
> 	<!ELEMENT MammalType (#PCDATA)>
> <!ELEMENT Fish (FishName, FishType)>
> 		<!ATTLIST FishName (latin|common) "common">
> 	<!ELEMENT FishType (#PCDATA)>
> <!ELEMENT Bird (BirdName, BirdType)>
> 		<!ATTLIST BirdName (latin|common) "common">
> 	<!ELEMENT BirdType (#PCDATA)>
> Image dozens of elements like this!
> Is there a way (either with a Schema or a DTD) to generalise this type of
> structure such that:
> <!ELEMENT * (*Name, *Type)>
> 		<!ATTLIST *Name (latin|common) "common">
> 	<!ELEMENT *Type (#PCDATA)>

I don't know if this is doable with the W3C xml-schema
Working Draft -- I don't imagine that it is, but I haven't
really looked at the WD lately -- but DTDs offer a
partial solution that might be helpful in your circumstance.

The idea is to define a "meta-DTD" that looks like:

    <!ELEMENT Animal     (AnimalName, AnimalType) >
    <!ATTLIST AnimalName (latin|common) "common" >
    <!ELEMENT AnimalType (#PCDATA)>

Then in the actual DTD you use #FIXED attributes
on the specific element types to specify the
abstract type to which they conform:

    <!ATTLIST Fish     AnimalForm CDATA #FIXED "Animal" >
    <!ATTLIST FishName AnimalForm CDATA #FIXED "AnimalName" >
    <!ATTLIST FishType AnimalForm CDATA #FIXED "AnimalType" >
    <!ATTLIST Bird     AnimalForm CDATA #FIXED "Animal" >
    <!ATTLIST BirdName AnimalForm CDATA #FIXED "AnimalName" >
    <!ATTLIST BirdType AnimalForm CDATA #FIXED "AnimalType" >
    <!-- ... etc -->

Of course this doesn't make writing the DTD any simpler --
each specific element type still needs to be declared,
and the #FIXED attributes have to be specified on top of that --
but it *can* make things much simpler for processors:
Instead of having to write code to handle each of Mammal,
Bird, Fish, Reptile, et cetera, processors can key off
of the 'AnimalForm' attribute to decide what to do.

Then, if you later need to add a new class of elements,
you only need to modify the DTD:

    <!ELEMENT Dinosaur     (DinosaurName, DinosaurType) >
    <!ATTLIST DinosaurName (latin|common) "common">
    <!ELEMENT DinosaurType (#PCDATA)>
    <!ATTLIST Dinosaur     AnimalForm CDATA #FIXED "Animal" >
    <!ATTLIST DinosaurName AnimalForm CDATA #FIXED "AnimalName" >
    <!ATTLIST DinosaurType AnimalForm CDATA #FIXED "AnimalType" >

and all of the processing tools which are designed to
work with the "Animal" architecture will automatically
know how to deal with Dinosaurs.

This is a design pattern commonly known in the SGML community
as "Architectural Forms". 

--Joe English



News | XML in Industry | Calendar | XML Registry
Marketplace | Resources | MyXML.org | Sponsors | Privacy Statement

Copyright 2001 XML.org. This site is hosted by OASIS