<!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&nbsp;</span> <a href="http://www.vbxml.com/members/profile.asp?id=i1005">Dimitre Novatchev</a> </td> </tr> <tr> <td>&nbsp;</td> </tr> </table> <!– Table1 –> <table padding="1" border="1" class="snippet-header-text"> <tr > <td class="snippet-header-property"> Language&nbsp; </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&nbsp; Mar&nbsp; 2001 </td> </tr> <tr > <td> Updated </td> <td noWrap class="snippet-header-text"> 27&nbsp; Mar&nbsp; 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>&nbsp;</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>&nbsp;</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>&nbsp;</td></tr> <tr class="snippet-italic"> <td> A student will have specified these as </td> </tr> <tr> <tr>&nbsp;</tr> <td class="snippet-codeg"> <pre><code><font color="#0000FF">&lt;</font><font color="#800000">thesis faculty</font><font color="#0000FF">=&quot;</font><b>arts</b><font color="#0000FF">&quot; </font><font color="#800000">department</font><font color="#0000FF">=&quot;</font><b>history</b><font color="#0000FF">&quot; </font><font color="#800000">options</font><font color="#0000FF">=&quot;</font><b>foo bar blort</b><font color="#0000FF">&quot;&gt;</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>&nbsp;</td></tr> <tr > <td> We want to allow foo.sty and bar.sty, but to discard blort.sty </td> </tr> <tr><td>&nbsp;</td></tr> <tr > <td> The idea for the solution is to use the id() function. </td> </tr> <tr><td>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</td></tr> <tr > <td> When applied on the following xml source document: </td> </tr> <tr> <tr>&nbsp;</tr> <td class="snippet-codeg"> <pre><code><font color="#0000FF">&lt;</font><font color="#800000">thesis faculty</font><font color="#0000FF">=&quot;</font><b>arts</b><font color="#0000FF">&quot; </font><font color="#800000">department</font><font color="#0000FF">=&quot;</font><b>history</b><font color="#0000FF">&quot; </font><font color="#800000">options</font><font color="#0000FF">=&quot;</font><b>foo bar blort</b><font color="#0000FF">&quot;/&gt;</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>&nbsp;</td></tr> <tr> <td> There are some interesting things to note about this solution: </td> </tr> <tr><td>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</tr> <td class="snippet-codeg"> <pre><code><font color="#0000FF">&lt;</font><font color="#800000">xsl:for-each select</font><font color="#0000FF">=&quot;</font><b>document('')/*</b><font color="#0000FF">&quot;&gt;</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>&nbsp;</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>&nbsp;</td></tr> <tr class="snippet-header-property"> <td> XML Source </td> </tr> <tr><td>&nbsp;</td></tr> <tr> <td> <iframe id="dispSource" height="50px" name="dispSource" src="xsValidateEnforceAttribute.xml" rows="12"></iframe> </td> </tr> <tr><td>&nbsp;</td></tr> <tr class="snippet-header-property"> <td> XSL Stylesheet </td> </tr> <tr><td>&nbsp;</td></tr> <tr> <td> <iframe id="dispStyle" height="500px" name="dispSource" src="xsValidateEnforceAttribute.xsl" rows="50"></iframe> </iframe> </td> </tr> </table> </body> </html>