Sophie

Sophie

distrib > Mageia > 7 > i586 > by-pkgid > b3bdfe6d859a3d6920ff2c44b38e9a6f > files > 272

saxon-manual-9.4.0.9-2.mga7.noarch.rpm

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet href="../make-menu.xsl" type="text/xsl"?><html>
   <head>
      <this-is section="extensibility" page="instructions" subpage=""/>
      <!--
           Generated at 2011-12-09T20:47:22.916Z--><title>Saxonica: XSLT and XQuery Processing: Writing XSLT extension instructions</title>
      <meta name="coverage" content="Worldwide"/>
      <meta name="copyright" content="Copyright Saxonica Ltd"/>
      <meta name="title"
            content="Saxonica: XSLT and XQuery Processing: Writing XSLT extension instructions"/>
      <meta name="robots" content="noindex,nofollow"/>
      <link rel="stylesheet" href="../saxondocs.css" type="text/css"/>
   </head>
   <body class="main">
      <h1>Writing XSLT extension instructions</h1>
      <p><i>This feature is available in Saxon-PE and Saxon-EE only.</i></p>
      <p>Saxon implements the element extensibility feature defined in the XSLT standard.
 This feature allows you to define your own instruction types for use in the stylesheet. These
 instructions can be used anywhere within a <i>content constructor</i>, for example as a child
 of <code>xsl:template</code>, <code>xsl:if</code>, <code>xsl:variable</code>, or of a literal
 result element.</p>
      <p><i>User-written extension instructions are not currently supported on the .NET platform.</i></p>
      <p>To implement and use extension instructions, three steps are necessary:</p>
      <ol>
         <li>
            <p>There must be a class that implements the interface 
            <a class="bodylink"
                  href="../javadoc/com/saxonica/xsltextn/ExtensionElementFactory.html"><code>ExtensionElementFactory</code></a>,
            which recognizes all the extension elements in a particular namespace and provides the Java
            code to implement them.</p>
         </li>
         <li>
            <p>This factory class must be associated with a namespace URI and registered with the 
         <a class="bodylink" href="../javadoc/net/sf/saxon/Configuration.html"><code>Configuration</code></a>, which can be done either by
            calling the method <a class="bodylink"
                  href="../javadoc/net/sf/saxon/Configuration.html#setExtensionElementNamespace"><code>setExtensionElementNamespace(namespace, classname)</code></a>, or by means
            of an entry in the configuration file.</p>
         </li>
         <li>
            <p>Within the stylesheet, there must be a namespace declaration that binds a prefix to this
         namespace URI, and the prefix must be declared as an extension namespace by means of the
         <code>extension-element-prefixes</code> attribute, typically on the <code>xsl:stylesheet</code> element.
         (A rarely-used alternative is to declare it in the <code>xsl:extension-element-prefixes</code> attribute
         of an enclosing literal result element.)</p>
         </li>
      </ol>
      <p>Saxon itself provides a number of stylesheet elements beyond those defined in the
XSLT specification, including <code>saxon:assign</code>, <code>saxon:entity-ref</code>, 
and <code>saxon:while</code>. To enable these, use the standard XSLT extension mechanism: define
<code>extension-element-prefixes="saxon"</code> on the xsl:stylesheet element, or 
<code>xsl:extension-element-prefixes="saxon"</code> on any enclosing literal result element.</p>
      <p>Any element whose prefix matches a namespace listed in the <code>extension-element-prefixes</code>
 attribute of an enclosing element is treated as an extension element. If no class can be
 instantiated for the element (for example, because no <a class="bodylink"
            href="../javadoc/com/saxonica/xsltextn/ExtensionElementFactory.html"><code>ExtensionElementFactory</code></a> has been
         registered for the relevant namespace,
 or because the <code>ExtensionElementFactory</code> doesn't recognise the local name), then fallback
 action is taken as follows. If the element has one or more <code>xsl:fallback</code> children, they are
 processed. Otherwise, an error is reported. When <code>xsl:fallback</code> is used in any other context, it
 and its children are ignored.</p>
      <p>Within the stylesheet it is possible to test whether an extension element is implemented by using the system
 function <code>element-available()</code>. This returns true if the namespace of the element identifies
 it as an extension element (or indeed as a standard XSLT instruction) and if a class can be instantiated
 to represent it. If the namespace is not that of an extension element, or if no class can be
 instantiated, it returns false.</p>
      <p>The interface <a class="bodylink"
            href="../javadoc/com/saxonica/xsltextn/ExtensionElementFactory.html"><code>net.sf.saxon.style.ExtensionElementFactory</code></a> interface.
defines a single method, <code>getExtensionClass()</code>, which takes the local name of the element
(that is, the name without its namespace prefix) as a parameter, and returns the Java class used to
implement this extension element (for example, <code>return SQLConnect.class</code>). The class returned must
be a subclass of <code>net.sf.saxon.style.StyleElement</code>, and the easiest way to implement it is as a subclass of
<code>net.sf.saxon.style.ExtensionInstruction</code>.</p>
      <p class="subhead">Implementing extension instructions</p>
      <p>The best way to see how to implement an extension element is by looking at the example, for SQL
 extension elements, provided in package <code>net.sf.saxon.option.sql</code>, and at the sample stylesheet <b>books-sql.xsl</b>
         which uses these extension elements. Start with the class 
         <a class="bodylink"
            href="../javadoc/net/sf/saxon/option/sql/SQLElementFactory.html"><code>net.sf.saxon.option.sql.SQLElementFactory</code></a></p>
      <p>The <code>StyleElement</code> class represents an element node in the stylesheet document. Saxon calls methods
 on this class to validate and type-check the element, and to generate a node in the expression tree that is
 evaluated at run-time. Assuming that the class is written to extend <a class="bodylink" href="../javadoc/net/sf/saxon/style/ExtensionInstruction.html"><code>ExtensionInstruction</code></a>,
 the methods it should provide are:</p>
      <table>
         <tr>
            <td content="para">
               <p>prepareAttributes()</p>
            </td>
            <td content="para">
               <p>This is called while the stylesheet tree is still being built, so it should not attempt
    to navigate the tree. Its task is to validate the attributes of the stylesheet element and
    perform any preprocessing necessary. For example, if the attribute is an attribute value template,
    this includes creating an Expression that can subsequently be evaluated to get the AVT's
    value.</p>
            </td>
         </tr>
         <tr>
            <td content="para">
               <p>validate()</p>
            </td>
            <td content="para">
               <p>This is called once the tree has been built, and its task is to check that the stylesheet
    element is valid "in context": that is, it may navigate the tree and check the validity of the element in
    relation to other elements in the stylesheet module, or in the stylesheet as a whole. 
    By convention, a parent element contains checks on its children, rather than the other way around: this allows
    child elements to be reused in a new context without changing their code. The system will automatically call the
    method <code>mayContainSequenceConstructor()</code>. If this returns true, it will automatically check that all
    the children are instructions (that is, that their <code>isInstruction()</code> method returns true).If the extension element is not allowed to have any children, you can call <code>checkEmpty()</code> from
    the <code>validate()</code> method. However, users will normally expect that an extension instruction is allowed
    to contain an <code>xsl:fallback</code> child instruction, and you should design for this.If there are any XPath expressions in attributes of the extension instruction (for example a <code>select</code>
    attribute or an attribute value template), then the <code>validate()</code> method should call the 
    <code>typeCheck()</code> method to process these expressions: for example 
    <code>select = typeCheck("select", select);</code>
            </p>
            </td>
         </tr>
         <tr>
            <td content="para">
               <p>compile()</p>
            </td>
            <td content="para">
               <p>This is called to create an Expression object which is added to the expression tree. See below
    for further details.</p>
            </td>
         </tr>
         <tr>
            <td content="para">
               <p>isInstruction()</p>
            </td>
            <td content="para">
               <p>This should return true, to ensure that the element is allowed to appear
    within a template body.</p>
            </td>
         </tr>
         <tr>
            <td content="para">
               <p>mayContainSequenceConstructor()</p>
            </td>
            <td content="para">
               <p>This should return true, to ensure that the element can contain instructions.
    Even if it can't contain anything else, extension elements should allow an xsl:fallback
    instruction to provide portability between processors</p>
            </td>
         </tr>
      </table>
      <p>The <a class="bodylink" href="../javadoc/net/sf/saxon/style/StyleElement.html"><code>StyleElement</code></a> class has access to many services supplied either via its superclasses or via
 the XPathContext object. For details, see the API documentation of the individual classes.</p>
      <p>The simplest way to implement the <code>compile()</code> method is to return an instance of a class that is
 defined as a subclass of <code>SimpleExpression</code>. However, in principle any <a class="bodylink" href="../javadoc/net/sf/saxon/expr/Expression.html"><code>Expression</code></a> object
 can be returned, either an expression class that already exists within Saxon, or a user-written implementation.
 A subclass of <code>SimpleExpression</code> should implement the methods <code>getImplementationMethod()</code> and
 <code>getExpressionType()</code>, and depending on the value returned by <code>getImplementationMethod()</code>,
 should implement one of the methods <code>evaluateItem()</code>, <code>iterate()</code>, or <code>process()</code>.</p>
      <table width="100%">
         <tr>
            <td>
               <p align="right"><a class="nav" href="output-filters.xml">Next</a></p>
            </td>
         </tr>
      </table>
   </body>
</html>