<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<link rel="stylesheet" href="...css"/>
<title>Validating and Enforcing a list of attributes</title>
</head>
<body>
<font face="Arial" size="2">
<h1>Validating and enforcing a list of attribute values</h1>
</font>
<table border="0">
<tr>
<td>
<span class="snippet-header-property">By </span>
<a href="http://www.vbxml.com/members/profile.asp?id=i1005">Dimitre Novatchev</a>
</td>
</tr>
<tr>
<td> </td>
</tr>
</table>
<!– Table1 –>
<table padding="1" border="1" class="snippet-header-text">
<tr >
<td class="snippet-header-property">
Language
</td>
<td noWrap>
XSLT
</td>
</tr>
<tr >
<td>
Category
</td>
<td noWrap class="snippet-header-text">
dtd, xml, designpatterns
</td>
</tr>
<tr >
<td>
Posted
</td>
<td noWrap class="snippet-header-text">
27 Mar 2001
</td>
</tr>
<tr >
<td>
Updated
</td>
<td noWrap class="snippet-header-text">
27 Mar 2001
</td>
</tr>
</table>
<table border="0" class="snippet-header-text">
<tr>
<td class="snippet-header-property">Summary</td>
</tr>
<tr>
<td>
This snippet presents a method of validating if
a list of names (specified as an atrribute value) contains names from a
given "approved" list of values. Categories: XSLT, DTD, id() function,
validation.
</td>
</tr>
<tr><td> </td></tr>
<tr>
<td>
This problem was raised by Peter Flynn in the XSLT
mailing list
</td>
</tr>
<tr>
<td>
<a href="http://sources.redhat.com/ml/xsl-list/2001-02/msg00215.html">http://sources.redhat.com/ml/xsl-list/2001-02/msg00215.html</a>
</td>
</tr>
<tr><td> </td></tr>
<tr class="snippet-italic">
<td>
Imagine letting students specify the
options (actually allowed stylesheet names) for printing their
thesis.
</td>
</tr>
<tr><td> </td></tr>
<tr class="snippet-italic">
<td>
A student will have specified these as
</td>
</tr>
<tr>
<tr> </tr>
<td class="snippet-codeg">
<pre><code><font color="#0000FF"><</font><font color="#800000">thesis faculty</font><font color="#0000FF">="</font><b>arts</b><font color="#0000FF">" </font><font color="#800000">department</font><font color="#0000FF">="</font><b>history</b><font color="#0000FF">" </font><font color="#800000">options</font><font color="#0000FF">="</font><b>foo bar blort</b><font color="#0000FF">"></font></code></pre>
</td>
</tr>
<tr class="snippet-italic">
<td>
where foo.sty, bar.sty, and blort.sty are among the allowed options (ie declared entities in the DTD) for translation to LaTeX's .
Just a safety check to make sure a student doesn't go haywire."
</td>
</tr>
<tr><td> </td></tr>
<tr >
<td>
We want to allow foo.sty and bar.sty, but to discard blort.sty
</td>
</tr>
<tr><td> </td></tr>
<tr >
<td>
The idea for the solution is to use the id() function.
</td>
</tr>
<tr><td> </td></tr>
<tr >
<td>
The actual implementation (first presented by Jeni Tennison) has
since then been put into the XSLT FAQ site of Dave Pawson
</td>
</tr>
<tr>
<td><a href="http://dpawson.co.uk/xsl/muench.html#N38692">(http://dpawson.co.uk/xsl/muench.html#N38692)</a></td>
</tr>
<tr><td> </td></tr>
<tr >
<td>
It doesn't involve recursive templates, as long as one doesn't mind repeating in the stylesheet the list of allowed options.
</td>
</tr>
<tr><td> </td></tr>
<tr >
<td>
It has the advantage that one can deal with bad values (e.g. if 'blort' wasn't actually allowed) within the stylesheet.
</td>
</tr>
<tr><td> </td></tr>
<tr >
<td>
When applied on the following xml source document:
</td>
</tr>
<tr>
<tr> </tr>
<td class="snippet-codeg">
<pre><code><font color="#0000FF"><</font><font color="#800000">thesis faculty</font><font color="#0000FF">="</font><b>arts</b><font color="#0000FF">" </font><font color="#800000">department</font><font color="#0000FF">="</font><b>history</b><font color="#0000FF">" </font><font color="#800000">options</font><font color="#0000FF">="</font><b>foo bar blort</b><font color="#0000FF">"/></font></code></pre>
</td>
</tr>
<tr >
<td>
The xsl stylesheet below will produce the following result:
</td>
</tr>
<tr>
<td class="snippet-result" align="center">
Options: foo, bar
</td>
</tr>
<tr><td> </td></tr>
<tr>
<td>
There are some interesting things to note about this solution:
</td>
</tr>
<tr><td> </td></tr>
<tr>
<td>
1. In order to use the id() function, an attribute must be defined as ID in the DTD.
</td>
</tr>
<tr><td> </td></tr>
<tr>
<td>
2. To make it independent from any particular xml source document, the element having an ID - type attribute is made part of the stylesheet.
</td>
</tr>
<tr><td> </td></tr>
<tr>
<td>
3. Because of the previous two considerations the stylesheet must have its own DTD describing the ID - typed attribute.
</td>
</tr>
<tr><td> </td></tr>
<tr>
<td>
4. In order to get the id() function select nodes from the stylesheet, the stylesheet must be made the current document. This is achieved by the following:
</td>
</tr>
<tr>
<tr> </tr>
<td class="snippet-codeg">
<pre><code><font color="#0000FF"><</font><font color="#800000">xsl:for-each select</font><font color="#0000FF">="</font><b>document('')/*</b><font color="#0000FF">"></font></code></pre>
</td>
</tr>
<tr>
<td>
5. This solution has been tested to work successfully only with the SAXON xslt processor
</td>
</tr>
<tr><td> </td></tr>
<tr>
<td>
To summarise, this is a general method for validating and enforcing a list of allowed names as values of an attribute.
</td>
</tr>
<tr><td> </td></tr>
<tr class="snippet-header-property">
<td>
XML Source
</td>
</tr>
<tr><td> </td></tr>
<tr>
<td>
<iframe id="dispSource" height="50px" name="dispSource" src="xsValidateEnforceAttribute.xml" rows="12"></iframe>
</td>
</tr>
<tr><td> </td></tr>
<tr class="snippet-header-property">
<td>
XSL Stylesheet
</td>
</tr>
<tr><td> </td></tr>
<tr>
<td>
<iframe id="dispStyle" height="500px" name="dispSource" src="xsValidateEnforceAttribute.xsl" rows="50"></iframe>
</iframe>
</td>
</tr>
</table>
</body>
</html>