[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
Re: [xml-dev] Best Practice: constrain an element's content by (1)a run-time selection of alternate types or (2) a run-time selection of childelements using an XPath expression?
- From: Philippe Poulard <philippe.poulard@sophia.inria.fr>
- To: "Costello, Roger L." <costello@mitre.org>
- Date: Tue, 12 May 2009 10:33:44 +0200
Costello, Roger L. a écrit :
> <Publication kind="book">
> <Title>Everything is Miscellaneous</Title>
> <Author>David Weinberger</Author>
> <Date>2007</Date>
> <ISBN>0-8050-8811-3</ISBN>
> <Publisher>Henry Holt and Company, LLC</Publisher>
> </Publication>
>
> <Publication kind="magazine">
> <Title>Science News</Title>
> <Date>2005</Date>
> </Publication>
>
> PROBLEM STATEMENT
>
> What is best practice for constraining the content of Publication?
Hi,
This was the topic of my talk at Balisage last year:
http://www.balisage.net/Proceedings/html/2008/Poulard01/Balisage2008-Poulard01.html
Slides:
http://hal.inria.fr/docs/00/32/26/61/ANNEX/Bal2008poul061003.pdf
> APPROACH #1: ALTERNATE TYPES
> Create a BookType and a MagazineType and then select one of them to be Publication's type depending on @kind:
>
> if @kind = 'book' then select BookType
> else select MagazineType
>
> Here's how it is expressed in XML Schema 1.1:
>
> <xs:element name="Publication" type="PublicationType">
> <xs:alternative test="@kind eq 'magazine'" type="MagazineType" />
> <xs:alternative test="@kind eq 'book'" type="BookType" />
> </xs:element>
>
>
> You see the (new) <alternative> element being used to select a type for Publication based on the value of @kind.
When designing declarative markup languages, one often try to put in a
single vocabulary things that are specialized whereas one can
generalized some of them: <xs:alternative> is roughly an if-then-else or
a switch-case statement, but specialized for a specific purpose and
appliable to select a type (more or less). If we need another context
where an alternative is needed, we will need to once again upgrade the
language and invent a new <xs:alternative2> element and next a new
<xs:alt> element (this time with a variation of the name) and so on.
A single one is sufficient.
Moreover, it doesn't have to belong to that vocabulary: imagine you have
to patch XHTML with markup languages for making maths or graphics, would
you design markups in the XHTML namespace ? Not at all, just pick MathML
and SVG. Why would it be different for markup languages designed for
processing purpose such as schema (among others) ?
What is missing in the XML landscape is a kind of glue that allows
different XML vocabularies to cooperate, even when they are declarative
languages and imperative languages, in the same way that JSP/JSTL/taglib
are working, except that they are tightly coupled to Java, work only
within a Web server, and are not so much declarative.
My own efforts in that way is called Active Tags, and I have designed in
this framework an experimental schema language called the Active Schema
Language (ASL) that works like this. You can download the engine and try
it with the following examples:
http://reflex.gforge.inria.fr/tutorial-schemas.html
The draft of the spec:
http://ns.inria.fr/active-tags/active-schema/active-schema.html
With ASL, I would express the constraints exactly as mentionned:
<asl:element name="Publication">
<asl:attribute name="kind">
<xsl:text value="magazine"/>
<xsl:text value="book"/>
</asl:attribute>
<asl:sequence>
<asl:element ref-elem="Title"/>
<xsl:if test="{asl:element()/@kind='book'}">
<xsl:then>
<asl:element ref-elem="Author"/>
<asl:element ref-elem="Date"/>
<asl:element ref-elem="ISBN"/>
<asl:element ref-elem="Publisher"/>
</xsl:then>
<xsl:else>
<asl:element ref-elem="Date"/>
</xsl:else>
</xsl:if>
</asl:sequence>
</asl:element>
You should notice that <xcl:if> is borrowed from another namespace (not
shown here for brevity), and you can inject foreign elements in several
places as long as it makes sense in your schema; for example, if the set
of allowed values of an attribute were available in a database, just
loop on the resultset of an SQL or XQuery query and define text values
(<asl:text>) with each of them.
That way, the abstract tree of the schema is no longer static but
becomes dynamic: the schema can adapt itself to the data to validate
(switching content models) or whatever relevant in your constraints
(picking values from a database). That increases dramatically the
expressiveness of the language.
> APPROACH #2: XPATH EXPRESSION
>
> Here's how it is expressed in XML Schema 1.1:
>
> <xs:element name="Publication">
> <xs:complexType>
> <xs:sequence>
> <xs:element name="Title" type="xs:string" minOccurs="0"/>
> <xs:element name="Author" type="xs:string" minOccurs="0"
> maxOccurs="unbounded"/>
> <xs:element name="Date" type="xs:gYear" minOccurs="0"/>
> <xs:element name="ISBN" type="xs:string" minOccurs="0"/>
> <xs:element name="Publisher" type="xs:string" minOccurs="0"/>
> </xs:sequence>
> <xs:attribute name="kind" type="xs:string" />
> <xs:assert test="if (@kind eq 'book') then
> Title and Date and ISBN and Publisher and
> empty(* except (Title[1],Date[1],Author,ISBN[1],Publisher[1]))
> else
> if (@kind eq 'magazine') then
> Title and Date and empty(* except (Title[1],Date[1]))
> else
> Title and Date and
> empty(* except (Title[1],Date[1], Author))" />
> </xs:complexType>
> </xs:element>
I wonder how <xs:assert> can be implemented in a way that an XML editor
would propose the right element at the right moment; suppose the user
ask for the available elements after the <Title> of a magazine; would
the editor propose to the user an <Author>, but once selected the
assertion would say him he has an error ? Or the editor would try to
insert each candidate element and then apply the assertion in order to
prune those rejected from the candidate list ?
> WHICH IS BEST PRACTICE?
>
> Which approach is best practice?
IMHO, <xs:assert> is certainly useful in some cases, but should be
avoided as possible: this method let you apply a 2 phase constraint, the
former with the content model, the latter with the assertion, each
ignoring the other. Conversely, it is much more clean and efficient to
build content models dynamically: an editor would propose only the
elements that are really available in that context. With ASL, the
candidate elements available after the <Title> of a magazine are only a
single <Date> element.
--
Cordialement,
///
(. .)
--------ooO--(_)--Ooo--------
| Philippe Poulard |
-----------------------------
http://reflex.gforge.inria.fr/
Have the RefleX !
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]