# 4XSLT Processor

### Built-in Extension Elements

4XSLT supports user-defined extension elements as specified by the XSLT Recommendation. There are several extension elements built in, which are documented here.

####

    <ft:apply-templates
      select = node-set-expression
      mode = string-expression>
      <!-- Content: (xsl:sort | xsl:with-param)* -->
    </ft:apply-templates>

This is just like , except that you can set the mode using an XPath expression which resolves to a string qhich must be a qname. This qname is then used to select the mode as described in section 5.7 of the XSLT spec.

####

    <ft:write-file
      name = { string-expression }
      overwrite = { string expression }>
      <!-- Content: (ft:output, template) -->
    </ft:write-file>

This redirects a portion of the output to a file. The attribute is interpreted as an attribute value template. The string resulting from the AVT is the name of the output file. The attribute is interpreted as an attribute value template. If the resulting string is "yes", then the file is overwritten, otherwise the output is appended to the file, if it exists. Warning: ft:write-file is deprecated in favor of exslt:document. Please see the 4Suite EXSLT documentation.

The body of the element is a template, with all output generated by this templatemredirected to the file. The template may have embedded one or more elements as immediate children of . ft:output are empty elements with the same range of attributes as and the same semantics and defaulting for each attribute. All elements are combined, and the output parameters determined by each attribute is applied to the redirect file.

For example, this means that a 4XSLT transform can use the XML output method, but it can redirect sub-sections of its output to separate files using the HTML method for redirected output.

####

    <ft:message-output
      file = { string-expression }
      overwrite = { string-expression }
      disable = { string-expression } />

ft:message-output allows redirection of messages generated by xsl:message instructions to a file. The attribute is interpreted as an attribute value template. The string resulting from the AVT is the name of the output file. The attribute is interpreted as an attribute value template. If the resulting string is "yes", then the file is overwritten, otherwise the output is appended to the file, if it exists. The attribute is interpreted as an attribute value template. If the resulting string is "yes", then output from is disabled altogether.

### User-Defined Extension Elements

To define your own extension element, define an element derived from xml.xslt.XsltElement. The module in which it is defined must have global dictionary named "ExtElements" mapping element qualified names to element class objects. The element qnames are in the form of a tuple of two strings, the first being the namespace URI for the element, and the second being the local name. The namespace URI must be a valid, identifying (but not necessarily addressable) URI, and in particular, it cannot be an empty string.

Finally, modules containing any extension elements used must be indicated as such to the processor in one of two ways. (1) They are listed in the environment variable "EXTMODULES". "EXTMODULES" is a colon-separated list of modules. (2) They are registered with the processor using the registerExtensionModule() method, which takes a list of module names. In either case, all extension modules must should be in the "PYTHONPATH". Note that extension modules will automatically be searched for XPath extension functions as well as Extension elements.

For example:

    #extelement.py

    import string, os
    import xml.dom.ext
    from xml.xslt import XsltElement, XSL_NAMESPACE, AttributeValueTemplate

    class SystemElement(XsltElement):
        def __init__(self, doc, uri='http://foo.org/namespaces/ext-xslt', localName='system', prefix='xsl', baseUri=''):
            XsltElement.__init__(self, doc, uri, localName, prefix, baseUri)

        def setup(self):
            self.__dict__['_nss'] = xml.dom.ext.GetAllNs(self)
            self.__dict__['_command'] = AttributeValueTemplate.AttributeValueTemplate(self.getAttributeNS('', 'command'))
            return

        def instantiate(self, context, processor):
            origState = context.copy()
            context.setNamespaces(self._nss)
            command = self._command.evaluate(context)
            os.system(command)
            context.set(origState)
            return (context,)

    ExtElements = {
        ('http://foo.org/namespaces/ext-xslt', 'system'): SystemElement
        }

    #useext.py

    sheet = """<?xml version="1.0"?>
    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:ext="http://foo.org/namespaces/ext-xslt"
      extension-element-prefixes="ext"
      version="1.0">

      <xsl:template match="execute-command">
        <ext:system command="{@cmd}"/>
      </xsl:template>

    </xsl:stylesheet>
    """

    source = """<execute-command cmd="dir"/>"""

    from xml.xslt import Processor
    processor = Processor.Processor()
    processor.registerExtensionModules(['extelement'])
    processor.appendStylesheetString(sheet)
    result = processor.runString(source, ignorePis=1)
    print result

This example is somewhat involved, and shows how to allow an extension element use attribute value templates. If you don't need AVTs, you can just use an attribute's value directly.

Note the call to

    registerExtensionModules

in useext. This can be omitted if "extelement" (the module name where the extension element is defined) is in the EXTMODULES environment variable. This call should precede the appending of any stylesheet that uses the extension elements.

Note that 4XSLT supports fallback through the standard XSLT fallback mechanism. It also supports the element-available extension function.

### Extension Element API

#### Context

Most likely, the processing you'll do in extension code will reference the current XSLT context, which is passed into the instantiate method of all XSLT elements. This class is defined at xml.xslt.XsltContext.

As mentioned, XSLT Extension Elements should be derived from xml.xslt.XsltElement (or at least follow its protocol).

## Module xml.xslt

Module Summary

- Classes

### Classes

Class Summary
`XsltElement` |

#### Class XsltElement

Method Summary
`__init__` | Called as the stylesheet is being built. The DOM tree structure is not guarenteed to be set up in the initializer, so be careful of using node operations on self.
`setup` | Called after the stylesheet DOM structure has been set up, but before the processor has begun a run on any XML source. All node operations on self should have the expected result.
`instantiate` |

Method Details

#### __init__

`__init__(doc, uri, localName, prefix)`

> Called as the stylesheet is being built. The DOM tree structure is not guarenteed to be set up in the initializer, so be careful of using node operations on self.

> Parameters
> `doc` of type xml.dom.Document.Document

>   The stylesheet document node

> `uri` of type xml.dom.Document.Document

>   The element namespace URI

> `localName` of type xml.dom.Document.Document

>   The local element node name

> `prefix` of type xml.dom.Document.Document

>   The namespace prefix from the element qualified name

> Return Value

> > None

#### setup

`setup()`

> Called after the stylesheet DOM structure has been set up, but before the processor has begun a run on any XML source. All node operations on self should have the expected result.

> Parameters

> > None

> Return Value

> > None

#### instantiate

`instantiate(context, processor)`

> Parameters
> `context` of type xml.xslt.XsltContext

>   The current context, not yet updated with the namespace nodes defined on self.

> `processor` of type xml.xslt.Processor.Processor

>   The processor instance, used for output handler calls.

> Return Value
> tuple with the passed-on context as the first entry

>   This tuple is typically processed by the parent element. The only requirement is that the first argument be an XsltContext object, which can be the same as was passed in unless your element is intended to change any data in the context. Other items can be added to the tuple as needed to return data.