Re: Type-based design patterns
Hi Norm, > / Jeni Tennison <jeni@j...> was heard to say: > | I agree with this, very much. Actually I think we can break this > | pattern down into two classes: > | > | 1. grouping elements based on their *content* -- in other words, the > | *type* hierarchy > | > | 2. grouping elements based on their *context* -- in other words, the > | *substitution group* hierarchy > > As I consider the design of an XML Schema for DocBook, I wonder if I > need to be thinking more explicitly in terms of supporting 2 by > having, for example, all the list elements in the same substitution > group. I'm more inclined to use model groups, but maybe that's just > old design patterns. I guess that substitution groups give you a bit more of a *classification* semantic. It depends on the model group, of course. Model groups that are choices between several elements are much like substitution groups. Model groups that cover the entirety of an element's content when they're used are more like types. And then there are some model groups that don't fall into either camp, of course. (If you're considering whether or not to put substitution groups into a schema, I think it's the best choice if you want people to be able to add, e.g. new inline or block elements themselves -- all they have to do is declare their new element and have it point to the head element of that substitution group -- no fiddly (and under-specified) redefinition of model groups required. It's worth noting, though, that substitution groups and derivation by restriction can sometimes interact quite badly, but then so can model groups and derivation by restriction!) I feel I should back off from W3C XML Schema a bit though, and talk in the more general case. In the more general case, we just want to be able to label elements, with multiple labels, to indicate the kinds of things that they can do. A bit like interfaces for XML. We want to say "this element is a list (based on its content) *and* it is a block element (based on where it's used)", for example, and then say "all list elements should be treated like this, and all block elements like this", and to in some places use the fact that the element is a block element and in other places use the fact that it's a list element. (Importantly, the fact that something's a list and the fact it's a block are completely independent -- you can have blocks other than lists, and you can have inline lists.) I guess that what this means is that I think the *type* of an element, in XPath Data Model terms, should be a list of labels, gathered from both its type and substitution group (in W3C XML Schema terms). Unfortunately, types and substitution groups have different name spaces so there'd be clashes if it was done simplistically, but you get the general idea. What excites me about this possibility is that other schema technologies, such as RELAX NG and in particular Schematron, *or even XSLT* could be used to build data models with much more flexible labels than those W3C XML Schema naturally supports. With XSLT, you could label elements once by matching them against a pattern, and then that pattern could be essentially reused in many places. But I left reality some paragraphs back... > As I think about 2 though, I'm struck that I'm going to need the > equivalent of "next-match" in order for it to be useful. > > <xsl:template match="~ListType"> > <!-- some general stuff about all lists --> > <xsl:next-match/> > <!-- some general stuff about all lists --> > </xsl:template> > > <xsl:template match="orderedlist"> > <!-- some stuff about ordered lists --> > </xsl:template> > > I'm not going to feel like I got much benefit out of the type-based > matching if I have to write: > > <xsl:template match="~ListType"> > <!-- some general stuff about all lists --> > <xsl:choose> > <xsl:when test="local-name(.) = 'orderedlist'"> > </xsl:when> > <xsl:when test="local-name(.) = 'itemizedlist'"> > </xsl:when> > <!-- ... --> > </xsl:choose> > <!-- some general stuff about all lists --> > </xsl:template> (Tch, local-name()?!? You mean self::orderedlist, don't you? ;) I agree. Currently you have to do this by importing a stylesheet with the templates matching individual list types and do <xsl:apply-imports>. I've done this recently in order to add a linking semantic to (practically) all the elements in a document, and it's really messy having to split up your stylesheets like that. I agree that we need an <xsl:next-match> instead. That would mean making type-based matching have the highest priority in templates, which kinda feels a bit weird (isn't matching on type *more* general than matching by name?) but I don't think there's much we can do about that without turning template matching in XSLT completely upside down. Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format