XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

Learning to RELAX
by J. David Eisenberg | Pages: 1, 2

Attributes

XML tags can have attributes, and RELAX allows you to specify them in great detail. A news story, like HTML, can include an <img> tag which has a required src and optional width and height attributes. RELAX treats attributes as part of the tag, so the full specification of an image is as follows:

<elementRule role="img">
<sequence>
<!-- its sub-elements -->
</sequence>
</elementRule>

<tag name="img">
<attribute name="src" required="true" type="string"/>
<attribute name="width" type="positiveInteger"/>
<attribute name="height" type="positiveInteger"/>
</tag>

Notice that RELAX lets you specify that an image's width and height must be positive integers.

Just as it was possible to create a re-usable element specification, so it is possible to create a set of attributes that can be reused by many tags. For example, both the table body (<tbody>) and table header (<th>) elements have identical attributes for determining their horizontal and vertical alignment. This makes those attributes a perfect candidate for an attribute pool.

<attPool role="alignment">
<attribute name="align" type="string">
<enumeration value="left"/>
<enumeration value="center"/>
<enumeration value="right"/>
<enumeration value="justify"/>
</attribute>
<attribute name="valign" type="string">
<enumeration value="top"/>
<enumeration value="middle"/>
<enumeration value="bottom"/>
<enumeration value="baseline"/>
</attribute>
</attPool>

And now this attribute pool may be used in multiple tags.

<tag name="tbody">
<ref role="alignment"/>
</tag>

<tag name="th">
<ref role="alignment"/>
<attribute name="rowspan" type="integer">
<minInclusive value="1"/>
</attribute>
<attribute name="colspan" type="integer">
<minInclusive value="1"/>
</attribute>
</tag>

There are two things to note about this example:

  1. The <th> tag has attributes in addition to those included via the reference to the attribute pool;
  2. It's possible to set a range of valid values for numeric attributes.

Context-sensitive Elements

Practically everything we've done up to this point is possible with DTD specifications. Now let's examine something that RELAX can do that other methods can't do.

As the definition of a news story currently stands, both a list item (<li>) and the <body.content> tag may contain an information block (<block>) element. An information block may contain, among other things, <p>, <ul>, <ol> and <img> elements.

Let's say that we would like to set up news stories so that a block in the main body content can contain all these elements, but a block inside of list items may not contain images. To do this, we first set up the element rule for a <block> in the body content and the corresponding tag. Note that we have a label that is different from the role.

<elementRule role="block" label="block-in-content">
<mixed>
<choice occurs="*">
<ref label="p"/>
<ref label="ul"/>
<ref label="ol"/>
<ref label="img"/>
</choice>
</mixed>
</elementRule>

<tag name="block"/>

We then add another rule for the element that plays the role of a block, but this rule is labeled for use in a list.

<elementRule role="block" label="block-in-list">
<mixed>
<choice occurs="*">
<ref label="p"/>
<ref label="ul"/>
<ref label="ol"/>
</choice>
</mixed>
</elementRule>

Both of these rules are for elements that play the role of a “block.” In the definition of the <body.content> element, we refer to the appropriate <block> rule.

<elementRule role="body.content">
<ref label="block-in-content"/>
</elementRule>

And in the definition of a list item, we refer to the other rule.

<elementRule role="li">
<ref label="block-in-list"/>
</elementRule>

The <block> tag will now be validated differently, depending on the context in which it appears.

Controlling Element Models with Attributes

A news story can use the <money> tag to indicate that a number is a monetary amount. Its RELAX definition looks like

<elementRule role="money" type="decimal"/>
<tag name="money">
<attribute name="unit" type="string"/>
</tag>

Let's say we'd like to extend this definition so that there are two types of <money> elements, one for costs and another for balances. An item's cost is always positive; a company's balance can be either positive or negative. In other words, we'd like to be able to specify that

After paying  
<money unit="dollar" usage="cost">5</money> dollars,
the account had a balance of
<money unit="dollar" usage="balance">-10</money> dollars.

In this case, rather than using the context to choose the content of a tag, we want to use one of the tag's attributes to determine what content that tag may contain. To accomplish this, we'll need two element rules.

<!-- costs are greater than or equal to zero -->
<elementRule role="money-cost" label="money" type="decimal">
<minInclusive value="0"/>
</elementRule>

<!-- balances are unrestricted -->
<elementRule role="money-balance" label="money" type="decimal"/>

In the previous section, we had element rules with the same role and different labels; here we have element rules with the same label and different roles. Now we define elements that refer to the different roles:

<tag name="money" role="money-cost">
<attribute name="unit" type="string"/>
<attribute name="usage" type="string">
<enumeration value="cost"/>
</attribute>
</tag>

<tag name="money" role="money-balance">
<attribute name="unit" type="string"/>
<attribute name="usage" type="string">
<enumeration value="balance"/>
</attribute>
</tag>

Thus, the <money> tag plays the money-cost role when the usage attribute is cost; and it plays the money-balance role when its usage is balance.

Summary

Resources

RELAX Home Page
Detailed RELAX documentation: "How to RELAX"
RELAX FAQ
RELAX Mailing List
RELAX news from XMLhack
Relaxer, Java class generator for RELAX
RELAX verifier for XSLT

RELAX is a powerful markup language that permits you to specify how other XML documents are to be validated. You may, as with other specification methods

  • specify an element with an ordered sequence of sub-elements;
  • specify an element with a choice of sub-elements;
  • permit mixed content (text outside of tags); and
  • specify attributes for tags.

Additionally, RELAX gives you the power to

  • specify in great detail the type and range of data that an element may contain;
  • specify the type and range of values that an attribute may have;
  • permit a single tag to have different content depending upon the context in which it is used; and
  • permit a tag to have different content depending upon the value of that tag's attributes