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

 


Help: OASIS Mailing Lists Help | MarkMail Help

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: XML Schemas: Best Practices



I always fall back on making some parallels with OOP concepts.

In my mind, complexTypes are kind of like abstract classes, schema-scoped elements like instantiable classes and private (or type-scoped) elements like inner classes.  Inner classes are useful in
special circumstances, but you impact readability and reusability if you made every class except the outermost an inner class.

I would strongly discourage using type-scoped elements by default.  If you need to say that an element has a restricted content model due to its context, then you can use an type-scoped element with
the same tag name of an schema-scoped element.  I would avoid at all cost where the same tag name means two substantially different things within the same namespace.

If you make all of your elements type-scoped, the only element in your schema that is reusable in other schemas is the top-most.  Another schema could not reuse your Publication element.  Another
schema could define a distinct Publication element of its own that had the same structure as your Publication element, however that would not guarantee that it is supposed to mean the exact same
thing.

For example, if you had:

package org.example.Directory;
abstract class PersonType {}
class DogCatchers {
	class Person extends PersonType{}
	Person[] _members;
}
class Librarians {
	class Person extends PersonType{}
	Person[] _members;
}

Are the inner classes DogCatchers.Person and Librarians.Person equivalent?  We can tell that they are structurally equivalent, but the distinct classes might imply that they represent different things
and might need to be treated differently, or they might not.  But you couldn't imply that from the byte code and you would get an exception if you tried to add a member of the Librarians._members to
DogCatchers._members.  However, if it was:

class Person extends PersonType{}
class DogCatchers {
	Person[] _members;
}
class Librarians {
	Person[] _members;
}

You could tell that the author did not intend the specialize the interpretation of the class based on its context and you could have one person be both a DogCatcher and a Librarian.

My suggestions:

1) If an element represents a class of object, define the most general version of the element as a schema scoped element.

2) If a context restricts the appropriate content of an element that represents a class of object, then create a type-scoped variant of that element.

3) If an element represents an attribute or role name and is frequently used, make it a schema-scoped element.

4) If an element represents an attribute or role name and is very specific to its context, you may make it a type-scoped element.

5) If there is a reasonable expectation that a complexType might be reused make it a schema-scoped type.  

6) If you know that the complexType is very specific to an element, make it anonymous.

Don't force the processor to have to root through the schema infoset to guess if two elements are conceptually identical.  If you want an concept to be reusable, expose and use schema-scoped elements.

In your example, Title and Date (and possibly Author and Publisher) would fall under rule 3 (and since they are attributes, I would use a camelCase convention and call them <title>, <author> and
<date>.

PublicationType would fall under rule 5 (since it is reused as the base of BookType and MagazineType)

BookType and MagazineType may or may not fall under rule 6.

Magazine, Book and Catalogue would fall under rule 1.

Of course, these recommendations don't play well with the generic tagname, xsi:type subtyping convention that you were using in this example.  However, that convention doesn't work well across
namespaces since it is only the combination of namespace URI and tagname that allows me to be confident that elements in different contexts are supposed to represent the same concept.