[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
Best Practice: constrain an element's content by (1) a run-timeselection of alternate types or (2) a run-time selection of child elementsusing an XPath expression?
- From: "Costello, Roger L." <costello@mitre.org>
- To: "'xml-dev@lists.xml.org'" <xml-dev@lists.xml.org>
- Date: Mon, 11 May 2009 14:53:22 -0400
Hi Folks,
Consider this book publication:
<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>
Next, consider this magazine publication:
<Publication kind="magazine">
<Title>Science News</Title>
<Date>2005</Date>
</Publication>
Notice the *kind* attribute in both examples.
If its value is 'book' then the content of <Publication> is:
- Title
- Author
- Date
- ISBN
- Publisher
And if its value is 'magazine' then the content of <Publication> is:
- Title
- Date
PROBLEM STATEMENT
What is best practice for constraining the content of Publication?
XML SCHEMA 1.1 PROVIDES TWO APPROACHES
XML Schema 1.1 provides two approaches to constraining the content of the <Publication> element.
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.
(I don't show the complexType definition for MagazineType and BookType because it's the same as in XML Schema 1.0.)
APPROACH #2: XPATH EXPRESSION
Let the content of Publication be a collection of all the elements (both book elements and magazine elements) and set them optional:
- Title (0,1)
- Author (0, unbounded)
- Date (0,1)
- ISBN (0,1)
- Publisher (0,1)
Then create an XPath expression that selects the set of children for Publication depending on the value of @kind:
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
true()
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>
You see that the content of Publication is all the book and magazine elements and they are optional.
You see an XPath expression within the (new) <assert> element being used to constrain which child elements are allowed within Publication based on the value of @kind.
TWO APPROACHES
You have seen two ways of solving the problem of constraining the content of Publication:
(a) Run-time selection of alternate types
(b) Run-time selection of child elements using XPath
DEFINITION OF "RUN-TIME"
By "run-time" I mean that the content of Publication is not determined until an instance document is validated against a schema.
WHICH IS BEST PRACTICE?
Which approach is best practice?
What are the pros and cons of each approach?
/Roger
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]