The XForms Transform Function Module
__NUMBEREDHEADINGS__
- Document title:
- The XForms Transform Function Module
- Editors
- Nick Van den Bleeken, Inventive Designers
- Abstract
This document, developed by the Forms Working Group, specifies the transform function which is a module for XForms 1.2 and allows the transformation of an XML sub-tree.
- Status of this Document
- This is a live wiki document. Although it often reflects the best understanding of the editors and members of the Working Group, it may be inaccurate and has not necessarily been reviewed. If you need a stable copy, use the most recent official version: http://www.w3.org/TR/xformstransformfunction.
Copyright © 2010 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
Overview
The transform function allows you to do a transformation on an XML sub-tree. Depending on the XForms implementation different transformation languages can be supported. An example of a transformation language is XSLT.
The transform() Function
Object transform(string, node?)
This functions returns the result of the transformation of the provided XML sub-tree. The returned result can be either a node
or a string
depending on the result of the transformation. In the case of an XSL transformation the result is a node
if the XSL output method is XML (or XHTML), in all other cases the result is a string
. In the case of a node
the node
, and all of its descendants, will behave like they have a readonly
model item property with value true()
attached to them. The read-onlyness of the returned result can't be removed. The returned result will behave like an implicitly created instance with the root node having a readonly
model item property set to true()
, additionally there will be no way to remove the read-onlyness, not even with an explicit override using a bind element.
The first argument is the URI to the definition of the transformation (in the case of an XSL transformation it is the URI to an XSLT stylesheet). The optional second argument is the node that should be used as input for the transformation, when the second parameter is omitted the current context node will be used as input.
When the uri
doesn't points to a supported transformation definition or the transformation results in an error an xforms-compute-exception Event or xforms-binding-exception Event will be dispatched.
Examples:
<xforms:submission id="s1" ref="transform('my-stylesheet.xsl', instance())" resource="..."/>
<xforms:insert nodeset="n" origin="transform('my-stylesheet.xsl', instance())" />
Transform URIs and Instances
There may be occasions where the transform resides within an XForms instance, for example:
- The transform is potentially large so it would be more efficient to download it when the form is being constructed rather than upon demand of the initial transform
- The transform is the result of another transform, e.g. the default Schematron implementation genrates an XSLT transform from the original schema definition.
- The transform is augmented by user input before being applied to the instance data
- There are other aspects of the transform's retrieval, over HTTP, that require the richer facilities of an xf:submission in order that it may be dereferenced correctly.
With this in mind, it would be necessary to provide a version of, or option within, the transform function to reference a transform residing in an XForms instance. There is no means of overloading the function by argument type so there are potentially a number or alternate possibilities:
- One function for URIs and another for instances
- Use a simple fragment identifier
- Allow the use of XPointers in the URI
- Provide a new URI scheme for referencing internal resources
One function for URIs and another for instances
As described previously, the function can take a string value as its URI:
Object transform(string, node?)
The same function that accepts an XForms instance as the transform would have the following signature:
Object transform(node, node?)
This presents a problem for the interpretor in how to know what to do. The first uses a URI to reference the transform resource whilst the second would use an XPath expression to reference the instance containing the resource. This leads to the notion of having two separate functions, one for URI references and one for instances.
Possible suggestions for function names include:
URI: transform-uri, transform-from-uri, transform-with-uri
Instance: transform-instance, transform-from-instance, transform-with-instance
However, none of the above examples clearly state the action being performed, there is always some ambiguity as to what it is that is being transformed.
Use a simple fragment identifier
A URI's fragment identifier, when not preceded by a URI path takes its context as the parent document. Therefore, in this simplistic case, the form creator could quite rightly assume that because the transform's instance has an xs:ID of 'bar' that that can be referenced within the form via a fragment identifier.
<xforms:model> <xforms:submission id="s1" ref="transform('#bar', instance('foo'))" resource="..."/> <xforms:instance id="foo"> <foo> <bar>This is a test.</bar> </foo> </xforms:instance> <xforms:instance id="bar"> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> ... </xsl:transform> </xforms:instance>
Allow the use of XPointers in the URI
TBD
Provide a new URI scheme for referencing internal resources
The following example shows the transform function using an non-HTTP URI scheme, nominally defined as 'instance', and what follows is the ID of the referenced xf:instance:
<xforms:model> <xforms:submission id="s1" ref="transform('instance:bar', instance('foo'))" resource="..."/> <xforms:instance id="foo"> <foo> <bar>This is a test.</bar> </foo> </xforms:instance> <xforms:instance id="bar"> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> ... </xsl:transform> </xforms:instance>
Alternatively one could view this as a URN and reference it thus: urn:instance:bar
The Extended transform() Function (proposal)
It is not unusual for XSLT transformations to make use of parametric data, in addition to the instance being passed. In this proposal, the transformation function defined in the previous section carries a third parameter that is a referenced instance document, with each child of the root instance node being the name of a given parameter and each CDATA section or subordinate XML content being the value or subordinate XML node being passed to the transformation. The extended function is given as the following:
Object transform(
$URL as string, $dataInstance as node?, $parameterInstance as node? )
This functions returns the result of the transformation of the provided XML sub-tree. The returned result can be either a node
or a string
depending on the result of the transformation. The function performs as the transform() function in the previous section, but additionally uses the $parameterInstance to determine the parameters (including the associated namespaces) and values for the given transformation.
Examples:
<xforms:model> <xforms:instance id="foo"> <foo> <bar>This is a test.</bar> </foo> </xforms:instance> <xforms:instance id="params"> <params xmlns:alt="xmlns="http://www.myschema.org/xmlns/alt"> <name>Jane Doe</name> <id>jd125</id> <alt:date>2011-06-25</alt:date> </params> </xforms:instance> </xforms:model> <xforms:submission id="s1" ref="transform('my-stylesheet.xsl', instance('foo'), instance('params')" resource="..."/>
In this particular scenario, three parameters are passed to the transformation: name (with a value of 'Jane Doe'), id (with a value of 'jd123') and alt:date (with a value of '2011-06-25'), where alt is in the given namespace. Should there be a parameter in the transformation with the associated name, then it will override any internally defined parameters, otherwise, the variables will be ignored. That is to say,
<xsl:stylesheet xmlns="http://www.w3.org/1999/XSL/Stylesheet" xmlns:alt="http://www.myschema.org/xmlns/alt" version="1.0" > <xsl:param name="name" select="'John Doe'"/> <xsl:param name="id"/> <xsl:param name="salary" select="80000"/> <xsl:param name="alt:date/> <!-- Additional content --> </xsl:stylesheet>
Once the parameters are passed into the transformation, the parameters will have the name/value hashes of name:Jane Doe, id:jd123, salary:80000, alt:date:2011-06-25, respectively.
Any parameter that is in the xsl: namespace is treated as privileged, and is intended to pass critical information to the transformation itself. For instance, <xsl:mode>alpha</xsl:mode> indicates that the transformation start out in that mode of construction (that is, only <xsl:template> elements that have a @mode attribute value of "alpha" will be evaluated as the first template to be processed). as shown in the following instance example:
<xforms:model> <xforms:instance id="foo"> <foo> <bar>This is a test.</bar> </foo> </xforms:instance> <xforms:instance id="params" xmlns:alt="xmlns="http://www.myschema.org/xmlns/alt" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <params> <name>Jane Doe</name> <id>jd125</id> <alt:date>2011-06-25</alt:date> <xsl:mode>alpha</xsl:mode> <xsl:mediatype>text/xml</xsl:mediatype> <xsl:indent>yes</xsl:indent> </params> </xforms:instance> </xforms:model> <xforms:submission id="s1" ref="transform('my-stylesheet.xsl', instance('foo'), instance('params')" resource="..."/>
The xsl:mediatype overrides the <xsl:output element's @mediatype attribute, and so forth. A full list of these xsl parameters are still TBD, but may include the following.
Name | Values | Description |
---|---|---|
xsl:mode | any QName | Used to indicate that the matching root template must have the given QName for it's @mode attribute. This is frequently used when the same stylesheet might have multiple potential rendering approaches. |
xsl:method | text or xml or html or binary | In the <xsl:output>, this sets the method used for generating the type of output used by the transformation. |
xsl:mediatype | any mime type, such as text/xml or image/svg+xml | In the <xsl:output>, this sets the specific mime type that will be passed to the next processor in the transformation sequence. |
xsl:indent | yes or no | This sets whether the content is pretty printed (yes) or not (no). The default is 'no'. |
The parameters list makes use of the same conventions as the GET xforms-submission instance does - the containing instance element is immaterial (save as a place to declare namespaces global to the document), but the children of the parameters to be passed are treated as the parameter value names. It remains TBD as to whether if a parameter has a subordinate XML document that document is passed as the value, or whether this constitutes an error for the processor.
References
Normative references
- xforms-compute-exception
- TODO
- xforms-binding-exception
- TODO