XSLTForms/Print version
This is the print version of XSLTForms You won't see this message or any elements not part of the book's content when you print or preview this page. |
The current, editable version of this book is available in Wikibooks, the open-content textbooks collection, at
https://en.wikibooks.org/wiki/XSLTForms
Introduction
XSLTForms is a client-side implementation of XForms. It requires no plug-in in the browser, and it requires no special software on the server.
XSLTForms implements XForms by using XSLT to transform an input XHTML + XForms document to an XHTML+Javascript (AJAX) document; the XSL transformation is unique to XSLTForms.
The transformation can be run wherever an XSLT 1.0 engine is available. Some users run the transform server-side, using Apache and PHP; IIS and .NET; Jetty; or eXist). Others run it client-side, in the user's browser, using the XSLT engines built into Internet Explorer, Mozilla FireFox, Opera, Chrome, and Safari.
XForms is a technology for XML-based forms. It is defined by a specification developed by the World Wide Web Consortium, and many users of XForms use it for forms on the Web, but XForms is designed as a vocabulary module that can be plugged into any host XML vocabulary. One of the most widely used implementations of XForms is embedded in Open Office and uses the Open Document Format (Open Office's XML) as its host vocabulary. For an introduction to XForms you may want to consult a general introduction to the technology (several books have been published on paper and on the Web, including a WikiBook on the subject); in its current state this wikibook mostly focuses on topics specific to the XSLTForms implementation of XForms and won't suffice for you to learn XForms on your own.
This wikibook describes XSLTForms and its use as an XForms implementation. It begins with an introductory section that provides some background information on the package, then continues with some beginning examples. Later sections describe the use of XSLTForms with various HTTP servers and the solutions to common problems. The largest section of the wikibook is a description of the current status of XSLTForms, describing features implemented and not implemented, extensions to the specification and how to use them, and listing known restrictions of the implementation. Note that because XSLTForms is actively maintained, the status section has a disappointing tendency to fall out of date. You may have to take what it says with a grain of salt, and some of the limitations listed there may have been lifted by the time you read this book.
Background
XSLTForms has its origin in the AJAXForms project, an open source project (under the Lesser GNU Public License, LGPL) undertaken by AjaxForms S.L. of Pontevedra, Spain.
AJAXForms is a server-side XForms 1.0 implementation: it uses a Java program controlled by Ant to convert XForms documents (i.e. XML documents in the XHTML and XForms namespaces) into HTML documents and Javascript files. The result is an AJAX-based HTML page which behaves as specified by the XForm input, but which can be viewed and processed with Web browsers which do not support XForms natively.
The Java program used by AJAXForms to do the transformation is mainly based on an XSLT 1.0 transformation, but it also uses Jaxen (a Java XPath engine) to analyze XPath expressions.
AJAXForms has been dormant and unsupported since November 2006.
The XSLTForms project picked up the AJAX Javascript libraries developed by AJAXForms and replaced the Ant-driven server-side Java transformation with an XSLT 1.0 transformation that can run either on the server or in the browser. The first commits to the XSLTForms project's SourceForge repository were in November 2008. Since then, several versions of the software have been released; these have all been labeled beta as beta releases, until 2012, when a 1.0 release candidate (1.0RC) was put out. A second 1.0 release candidate (1.0RC2) was issued in 2014.
A number of users contribute comments, suggestions, and occasional code, but most of the work on XSLTForms is done by Alain Couthures, the founder of AgenceXML of Eysines, France (on the outskirts of Bordeaux).
Benefits
Benefits
editThere are a number of XForms implementations, with different strengths and weaknesses.
Among the strengths of XSLTForms are:
- ease of installation and use: Installation of XSLTForms on a Web server involves nothing more than copying the XSLTForms directory in the server's file space, and inserting an
xml-stylesheet
processing instruction at the top of each form. - longevity and active maintenance: XSLTForms has been actively developed and maintained for over a decade and active work continues.
- an active user community and ongoing support: users of XSLTForms use the SourceForge discussion list
xsltforms-support@lists.sourceforge.net
to provide mutual support - conformance: XSLTForms provides a good (though not perfect) level of conformance to the XForms specification.
- open source: XSLTForms is open source
- server-side processing: the XSLTForms transformation can be applied on the server, when deploying or serving the form; the transformation's output can if necessary then be tweaked further.
- client-side processing: the XSLTForms transformation can be performed in the client (providing the client supports XSLT); this reduces the load on the server.
Applications
Who uses XSLTForms?
For a start, XSLTForms ships with software products from a variety of sources.
- XSLTForms is a part of release 4.1 of Mark Logic's MarkLogic Server; the Mark Logic Application Builder is built using XSLTForms. A demonstration can be found at http://www.marklogic.com/products-and-services/application-builder/
- XSLTForms is also bundled with the open-source XML database eXist from version 1.4 on. A demonstration is available on the eXist Web site. There is also a section on XSLTForms and eXist in the XRX WikiBook.
- Xerox uses XSLTForms in its DocuShare product (among others), as well as in wikis, weblogs, and content-repository administrative pages; background information is given in a blog post on Leigh Klotz's Standards and Technology weblog.
A number of users and organizations use XSLTForms for their XForms applications. Some of these are publicly available tools for working with particular vocabularies:
- Joe Carmel (formerly the chief of Legislative Computer Systems at the U.S. House of Representatives) has published an information page and an XForm for editing documents in the StratML (Strategic Plan Markup Language) XML vocabulary. Andre Cusson of 01 Communications has extended Carmel's work to make a form for StratML Part 2 documents.
- Steven Cameron's Schema to XForms project uses XSLTForms for its interactive Schema Designer user interface.
- Oracc (the Online Richly Annotated Cuneiform Corpus, a collaborative effort of scholars at several institutions) uses XSLTForms to manage the search interface to the State Archives of Assyria Online (SAAo) and other corpora.
Other publicly available uses of XSLTForms are intended as demonstrations or examples:
- Alain Couthures maintains a set of XForms examples at the AgenceXML web site.
- The Open Siddur Project uses XSLTForms in its ("pre-alpha") demo of a Web application for putting together a siddur from component parts and compiling the results to HTML. [Broken when visited 20 July 2012]
- Steven Pemberton's tutorials XForms for HTML Authors and XForms for HTML Authors, Part 2 use XSLTForms for the free-standing examples of the form interactions.
- Michael Sperberg-McQueen has published a simulator for Nicklaus Wirth's PL/0 virtual machine which uses an XForms interface to step through the execution of the virtual machine.
Naming Conventions
In its current form, this book is the product of many hands. Usage of namespace prefixes and variable names is not consistent across the pages of the book.
As a step towards beginning to make the book more consistent, however, this page lists some conventions the reader will encounter in at least some page in the book.
Namespaces and namespace prefixes
editIt's not always convenient to provide explicit namespace declarations in every example in a book. In principle, the rules of XML namespaces mean that any prefix (including the empty prefix) can be used to denote any namespace, but as a convention, the namespace prefixes listed here will sometimes be used without declaration in examples. When that is the case, they should be understood as being bound to the namespaces indicated. (Often more than one prefix for the same namespace is listed here; that is one form of inconsistency in the current state of the book.)
- xf =
http://www.w3.org/2002/xforms
- ev =
http://www.w3.org/2001/xml-events
- xs =
http://www.w3.org/2001/XMLSchema
- xsd =
http://www.w3.org/2001/XMLSchema
- xsltforms =
http://www.agencexml.com/xsltforms
- rte =
http://www.agencexml.com/xsltforms/rte
[Note to authors / editors: add to this list!]
Other naming conventions
edit[more needed here]
Installing and Testing
Installing and using XSLTForms to support Web-based applications requires two steps:
- Download and install XSLTForms on your server, and point your forms to it as described below.
- If your forms involve submission of form data to the server, you'll need to make arrangements for your server to accept PUT or POST requests.
How these work depend on the context in which you are installing XSLTForms.
If you're using XSLTForms with a generic HTTP server, see below.
If you're using the version of XSLTForms included with MarkLogic server or the eXist XML database, both of these tasks are already taken care of for you, as part of the installation and configuration of the XML database. See the documentation!
Generic HTTP Server
This page describes installing XSLTForms in a generic Web server, e.g. Apache. If you are using XSLTForms with MarkLogic or with eXistDB, see the product-specific documentation.
Installing XSLTForms proper
editProspective users of XSLTForms are sometimes frustrated because they cannot find anything that look like proper installation instructions. (This page is an attempt to correct that situation, for those who find it.) Part of the problem is that some users find it hard to believe that installation of an XForms implementation can be as simple as it is.
Downloading XSLTForms
editFirst, you must download a copy of XSLTForms. The easiest thing to do is probably to go to the Sourceforge Project Home Page for XSLTForms and look for a download button; clicking on that button will cause your browser to download a ZIP file containing the most recent release package for the software.
When this page was last revised (February 2017), the most recent package was 1.0RC2 (1.0 release candidate 2).
Note: earlier releases are still available, including
- 1.0 RC, 18 Mar 2012
- Beta 3, 27 Feb 2011
- Beta3 Release Candidate, 12 Sep 2010
Unless you have a special need for an older version rather than the current version, however, you should take the latest available package.
Snapshot versions may be found by clicking on the Code tab or the SVN tag in the SourceForge project area. (When this page was last revised in February 2017, the most recent snapshot was r639, dated 20 Jan 2017.) Because the snapshot versions may include important enhancements or bug fixes, many users of XSLTForms use the snapshot versions for production work, rather than the most recent 'stable' version.)
Next, you must unzip the ZIP file and get it onto your HTTP server. Remember the location where you put it. (If you do not know how to get files onto your Web server, you will need to consult other sources to learn how to do that, before continuing here.)
Making your forms use XSLTForms
editFinally, you must add an XML stylesheet instruction to your XForms, which points to the xsltforms.xsl stylesheet in the package you just installed. So if your site is named forms.example.com and you installed XSLTForms in /lib/xsltforms-1.0RC/ and the xsltforms.xsl file is in that directory (do check, sometimes the release packages are wrapped in an extra layer and you'll find the stylesheet one directory level further down), you'll add a line like this (you may replace the newlines with a single blank; they are here to keep the lines short in the code block):
<?xml-stylesheet href="http://forms.example.com/lib/xsltforms-1.0RC/xsltforms.xsl" type="text/xsl"?>
to the XHTML+XForms documents you want to deliver with XSLTForms. In practice, you may prefer to use a relative URI rather than an absolute URI (so the stylesheet instruction will read ... href="../../../lib/xsltforms-1.0RC/xsltforms.xsl" ...); that makes it easier to test forms on a test machine before putting them on a production server.
Serving your forms with an appropriate MIME type
editA common source of problems at initial setup time is serving forms with an inappropriate MIME type.
- Forms served from an HTTP server should have a MIME type of
application/xml
,text/xml
, orapplication/xhtml
. Forms served astext/html
won't work: browsers don't apply XSLT stylesheets to HTML documents. - Forms loaded from a local file system will or won't work, depending on what MIME type the browser associates with the file extension. If
.html
doesn't work, try.xhtml
or.xml
.
Accepting PUT and POST
editArranging for your server to accept PUT or POST requests from an XForm is an entirely separate matter. In principle, setting the server up to handle such requests is completely independent of your XForms implementation (though in practice some server-side XForms implementations include server-side support for PUT and POST in the package).
This is not the place to go into details, but in general the options available include:
- installation of a WebDAV server (or more commonly configuration of some other server software to support WebDAV requests); possibilities include
- WebDAV support in Apache
- WebDAV / Delta V support in Subversion
- Apache support for WebDAV using Subversion as the file store
- the WebDAV interface in an XQuery database like eXist or BaseX
- WebDAV servers in MarkLogic
- configuration of a generic HTTP server to accept PUT or POST
Because they involve accepting and processing data from potentially unknown (and thus potentially untrustworthy and hostile) clients, PUT and POST unavoidably represent a security risk for your system. In consequence, most Webmasters and system administrators will have firm views on the right way to set things up to manage the risk properly. Users of XForms will need to work with the Webmaster to ensure that things are set up in a way that will let you get your work done and won't expose your site to unavoidable security problems.
XForms can be used as a convenient way to provide more sophisticated user interfaces for Web pages even without submitting data to a server, so for some purposes you may not need to set your server up for PUT and POST.
And for XForms applications you just want to run on your own machine, the support for file://
URIs in current versions of XSLTForms may make it unnecessary to configure a WebDAV server. (Need description of the Java applet elsewhere in the WikiBook, and need link to that description from here.)
ASP.NET
In ASP.NET, XSLTForms can be used server-side to process an XForm by invoking the asp:Xml Control, for example as follows:
<asp:Xml ID="Xml1"
runat="server"
DocumentSource="~/myform.xforms"
TransformSource="~/xsltforms/xsltforms.xsl"
EnableViewState="False"
></asp:Xml>
The ASP.NET DOM interface can be used to process submissions from the form, thus:
<%@ Page Language="C#" %>
<%
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load(Request.InputStream);
// process your xml here....
%>
Sources: This page was originally drafted based on information from William Velasquez, to whom thanks.
eXist-db
Please see XRX Chapter on XSLTForms and eXist
HelloWorld
If XSLTForms is installed correctly, the following form (or something very similar to it) should work.
<?xml-stylesheet href="xsltforms/xsltforms.xsl" type="text/xsl"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xforms="http://www.w3.org/2002/01/xforms"
xmlns:my="http://www.example.com/my-data">
<head>
<!--The Model is defined within the head of the xhtml document-->
<xforms:model>
<!--The instance is defined within the model-->
<xforms:instance>
<my:data>Hello World</my:data>
</xforms:instance>
</xforms:model>
</head>
<body>
<!--The view is defined within the body of the document-->
<xforms:group>
<xforms:output ref="/my:data">
<xforms:label>Output Control Example</xforms:label>
</xforms:output>
</xforms:group>
</body>
</html>
Notes:
The form includes an xml-stylesheet
processing instruction (line 1, highlighted). The value of the href
pseudo-attribute should be a relative reference to the xsltforms.xsl
stylesheet. The example assumes that the XSLTForms library is installed in the subdirectory xsltforms
; the value of the relative reference will need to vary depending on the relative location of the library, vis-a-vis the location of the form. In another context, for example, the processing instruction might read <?xml-stylesheet href="../../../lib/xsltforms-1.0RC2/xsltforms.xsl" type="text/xsl"?>
.
Instance Loading
An easy error to make is to give the wrong URI when pointing to an external instance (in the src
or resource
attribute).
Symptom: If the URI cannot be dereferenced, XSLTForms will raise an xforms-link-exception
; normally, this will result in a popup window reporting an XSLTForms Exception: Error dispatching event 'xforms-model-construct' : xforms-link-exception.
Possible diagnosis: An instance cannot be loaded.
Actually, xforms-link-exception may also arise in other contexts, as well, so this diagnosis is not certain. One way to confirm it is to comment out the xf:instance
element(s), one at a time, to see what happens. If commenting out an instance causes no change, that instance is unlikely to be the problem. If the instance is the source of the link error, commenting it out will normally cause the xforms-link-exception to be replaced by xforms-bind-exceptions.
Fix: get the URI right.
Form not correctly rendered
There may be many reasons a form is not correctly rendered.
For XForms embedded in XHTML documents, the following causes are common and easy to check for.
1. Bad MIME type
For XForms embedded in HTML documents, one common reason is that the document in question is being served with MIME type text/html
instead of application/xml
, text/xml
, application/xhtml
, application/xhtml+xml
, or another appropriate MIME type. [Cross reference to proper discussion of XForms MIME types needed here.]
When the document is served with an XML-related MIME type recognized by the browser, the browser will apply the XSLTForms stylesheet, which transforms the form into XHTML which the browser will understand natively, plus Javascript functionality to produce the prescribed XForms behaviors. When the document is served without an appropriate MIME type, no transformation will be undertaken, and the XForms controls will typically not be rendered.
The final control over what MIME type is associated with a document served by a Web server lies within the server's configuration. If you understand how to configure your server, you can control it however you like. If you don't, then the easiest approach is to rename the form from myform.html
to myform.xhtml
or myform.xml
. This exploits the common default associations of MIME types with file extensions.
Renaming the file also typically works for documents in the file system.
2. No xml-stylesheet processing instruction
Make sure you have a stylesheet pointer, with a form something like:
<?xml-stylesheet href="xsltforms/xsltforms.xsl" type="text/xsl"?>
3. xsltforms.xsl not found
Make sure the href
pseudo-attribute in your xml-stylesheet
processing instruction points to the right place.
Triggers not working
A common cause of triggers not working is that the actions in the trigger are not listening for any events.
The following trigger illustrates the problem. It is meant, when activated, to replace the value of the current element with the string "Hello <strong>World</strong>!
". But nothing happens when the trigger is pressed.
<trigger xmlns="http://www.w3.org/2002/xforms">
<label>Hello World!</label>
<setvalue ref="."
value="'Hello <strong>World</strong>!'"
/>
</trigger>
The solution is to specify the event(s) which will cause the setvalue
action to fire.
<trigger xmlns="http://www.w3.org/2002/xforms">
<label>Hello World!</label>
<setvalue ev:event="DOMActivate"
xmlns:ev="http://www.w3.org/2001/xml-events"
ref="."
value="'Hello <strong>World</strong>!'"
/>
</trigger>
CSS
Minimal Styling Rules
editThere are probably two basic kinds of layout that people might want:
(1) Inline Forms All Xform controls "flowing" into the page and moving to the next line when there isn't enough room for the control to fit on the end of the current line;
(2) Block Forms All XForm controls appearing each on a separate line down the page and aligned vertically.
By 'XForm controls' we mean the 'label', the 'value' and the associated 'icons' (help, valid/invalid). For both of the above cases we want all of the parts of the control to stay on the same line, a label shouldn't be separated from its value. So, in the first case all of the parts should move down to the next line if there isn't enough space.
Each xform control is converted to something like the following HTML structure via the XSLTForms stylesheet
span.xforms-control
|_span
|_span
|_span
|_span
| |_label
|_span.value
|_input
By default a span will have no 'display' function so by adding styling to the span elements created by XSLTForms we can achieve what we want.
So for minimal styling rules, firstly to get everything within an Xform control to stay together we can use the following CSS rule:
span.xforms-control span {display:inline-block; white-space:nowrap; }
Using 'white-space:nowrap' seems to be enough on most browsers but adding 'display:inline-block' seems to force the nowrap behaviour.
Then to make the control label appear to 'belong' to the control value we can set the width of the label and make it display as an inline-block as well:
label.xforms-label { display:inline-block; width:300px; text-align:right; margin-right:4px;}
The above two selectors seem to achieve the flow layout that you'd expect as default with HTML but also makes each XForm control behave as an atomic unit.
To get the second tabular layout is simply a matter of forcing each control to appear on a new line as follows:
span.xforms-control {display:block;}
The fact that we have made each label one standard width means that the values will align nicely.
However, if you don't want xform trigger buttons to behave the same way as other controls then instead you have to be more specific in your display:block selector, something like:
span.xforms-input, span.xforms-select1, span.xforms-textarea, span.xforms-output {display:block;}
XSLTForms classes for XForms pseudo-elements and pseudo-classes
editThe CSS XForms pseudo-element and pseudo-class selectors are not implemented in XSLTForms; instead, XSLTForms generates elements carrying equivalent classes that can be selected by CSS rules.
For example, instead of
/* Color current item yellow. */ ::repeat-index {background-color: yellow;} /* Within an invalid control, color the input field pink. */ :invalid ::value {background-color: pink;}
write
/* Color current item yellow. */ .xforms-repeat-item-selected {background-color: yellow;} /* Within an invalid control, color the input field pink. */ .xforms-invalid .xforms-value {background-color: pink;}
CSS | Equivalent XSLTForms class values |
---|---|
::value | .xforms-value |
::repeat-item | .xforms-repeat-item |
::repeat-index | .xforms-repeat-item-selected |
CSS | Equivalent XSLTForms class values |
---|---|
:enabled & :disabled | .xforms-enabled
.xforms-disabled |
:required & :optional | .xforms-required .xforms-optional |
:valid & :invalid | .xforms-valid .xforms-invalid |
:read-only & :read-write | .xforms-readonly .xforms-readwrite |
:out-of-range & :in-range | (Not implemented) |
:value-empty & :value-non-empty | (Not implemented) |
It helps to be clear about the nesting relations here. The pseudo-properties :valid
, :invalid
, etc. are assigned to controls; the pseudo-element ::value
is a child of the control, not the control itself. So neither the CSS selector ::value:invalid
nor the equivalent selector using the equivalent XSLTForms classes, .xforms-value.xforms-invalid
will select anything: the ::value
pseudo-element doesn't have the :invalid
class. Instead, the pseudo-element is inside an element with that class. (Theoretically, XForms says the ::value
pseudo-element is a child of the control; in practice, for practical reasons XSLTForms makes it a descendant, not a child.)
In case of doubt, careful study of the HTML generated by XSLTForms can help a form author understand how to write CSS selectors that select the intended elements.
TinyMCE
Like other XForms implementations, XSLTForms supports a non-standard control for editing mixed content (XML with a mixture of elements and character data).
XSLTForms can (at least in principle) be used either with CKEditor or with TinyMCE. This page describes the use of TinyMCE with XSLTForms. It is based on version 638 of XSLTForms; behavior may vary in other versions.
Framework for using TinyMCE with XSLTForms
editTo use TinyMCE as a control in an XForm, several things are necessary. A simple minimal example of using TinyMCE is available on the AgenceXML web site; it illustrates all the following points.
- A
script
element should point to the TinyMCE library and specify the TinyMCE version number. - An XSD schema should be provided, which defines an appropriate simple type for the element to be edited using TinyMCE; an
xsd:appinfo
element in the definition of this type contains the initialization object used by TinyMCE to customize the editor. - The element to be edited using TinyMCE should be bound to the simple type declared in the XSD schema.
Pointing to the TinyMCE Javascript and supplying a TinyMCE version number
editInclude an XHTML script
element with the following attributes:
type
with the valuetext/javascript
src
provides a reference to the TinyMCE library (relative to the XForm)data-uri
specifies which rich-text editor is being used; for TinyMCE, use the valuehttp://www.tinymce.com
data-version
specifies what version of TinyMCE is being used
The content can be vacuous; a Javascript comment (/* */
) will do.
For example:
<script type="text/javascript"
src="xsltforms/scripts/tinymce_4.0.21/tinymce.min.js"
data-uri="http://www.tinymce.com"
data-version="4.0.21"
>/* */</script>
The data-version attribute is used by XSLTForms to adjust its calls to TinyMCE; it distinguishes versions 3 and 4 of TinyMCE. (Or, to be more precise, it distinguishes versions whose number begins with "3." and all other versions.) Note, however, that not all versions of TinyMCE 4 work with XSLTForms version 638 (see below).
Supplying a richtext type and a TinyMCE initialization object
editA key part of using TinyMCE with XSLTForms is to provide an xsd:schema element, which can be embedded in the XHTML header. A very simple example follows:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xforms="http://www.w3.org/2002/xforms"
targetNamespace="http://www.agencexml.com/xsltforms/rte">
<xsd:simpleType name="standardHTML">
<xsd:restriction base="xforms:HTMLFragment" xsltforms:rte="TinyMCE"/>
<xsd:annotation>
<xsd:appinfo> {
plugins: [ "code" ],
toolbar: 'undo redo | bold italic | bullist'
} </xsd:appinfo>
</xsd:annotation>
</xsd:simpleType>
</xsd:schema>
As can be seen, this schema defines a simple type with a number of properties worth noting:
- The type's expanded name is
{http://www.agencexml.com/xsltforms/rte}standardHTML
. (It's not clear whether the name must be this one or can vary. [Conjecture (unconfirmed): it can vary, so that different instances of TinyMCE with different customizations can co-exist in the same form.]) - Its base type is
{http://www.w3.org/2002/xforms}HTMLFragment
. (This appears to be essential; there is code in xsltforms.js which checks for this.) - The
xsd:restriction
element in its definition carries the attribute-value specificationxsltforms:rte="TinyMCE"
(where the prefixxsltforms
is bound to namespacehttp://www.agencexml.com/xsltforms
). XSLTForms uses the value of this attribute to distinguish code specific to TinyMCE from code specific to CKEditor. - The type definition contains an
xsd:appinfo
element whose character-data content is a Javascript object. Strictly speaking, theappinfo
element is optional (a default of{ }
is assumed if none is present), but in practice it will almost always be needed. The Javascript object described in theappinfo
element will (with some modifications) be passed to TinyMCE as the argument to the TinyMCEinit()
function; it is the essential mechanism for customizing the TinyMCE.
Binding the instance to the richtext type
editThe element(s) to be edited using TinyMCE should be bound to the type declared for them in the schema described above.
For example:
<xf:bind nodeset="richtext" type="rte:standardHTML"/>
Note that the content of the element to be edited should be character data only: a string, with no child elements. The string may (and normally will) contain the serialized XML representation of elements and attributes.
See Serial form and XML form, below.
Serial form and XML form
editThe use of mixed-content editors like TinyMCE and CKEditor requires that the form designer distinguish carefully between what might be called the normal XML form of an XML document or fragment and the serialized form of the same material. Some other constructs pose the same challenge, like the transform()
and serialize()
functions and the setnode
action. (This topic has broad potential for confusion, since it is the serialized form of an XML document which is defined by the XML specification; the fact that we will sometimes be writing the serialized form of an XML element within an XML document also complicates things. The reader who finds the discussion here confusing is asked to be patient; experimentation with a form may also help.)
XML form
editWhat we here call the XML form of an instance document is represented in two different ways at different moments:
- In the XHTML+XForms document itself, it's represented as a normal XML document or element, using XML syntax.
- in a running instance of a form being delivered with XSLTForms, it's represented as a DOM object.
The former is illustrated by the following XForm fragment, showing an instance named normal-document whose root element is named data
and has one child named richtext
, which in turn has a child named charge
.
<xf:instance id="normal-document" xmlns="">
<data><richtext>
<charge>
<p>uncertain<en>
<p>Gruen (<i>Historia</i> 1966) 38 suggests a
<procedure pid="c-maiestas" lang="lat">maiestas</procedure>
trial for seditious behavior as tribune.</p>
</en></p>
</charge>
</richtext></data>
</xf:instance>
When this XML is read by an XForms processor, a data structure is built to represent it, following the rules of the Document Object Model (DOM).
In editing mixed content, however, TinyMCE does not operate on the DOM representation of the data; it operates on a string containing tags marked with angle brackets: the serialized form of the data to be edited. (The reasons for this design choice are obscure.)
Serialized form
editIf a document instance is intended to be edited using TinyMCE, using the normal XML form for the document will lead to unsatisfactory results. (TinyMCE will get the string value of the richtext
element, perhaps wrap it in a p
element (depending on configuration), and lose details like the attributes on procedure
.) To be usefully editable using TinyMCE, the instance document must be presented in serialized form, that is as a string containing a sequence of characters including angle brackets. To write such a string in an XML context (e.g. an XForm), one must escape the left angle brackets and ampersands appearing in the serialized form of the data. When this is done, the xf:instance
element will look something like this:
<xf:instance id="serialized-document" xmlns="">
<data><richtext>
<charge>
<p>uncertain<en><p>Gruen (<i>Historia</i> 1966) 38 suggests a <procedure pid="c-maiestas" lang="lat">maiestas</procedure> trial for seditious behavior as tribune.</p></en></p>
</charge>
</richtext></data>
</xf:instance>
Or alternatively (using a CDATA marked section) like this:
<xf:instance id="serialized-document-2" xmlns="">
<data><richtext><![CDATA[
<charge>
<p>uncertain<en>
<p>Gruen (<i>Historia</i> 1966) 38 suggests a
<procedure pid="c-maiestas" lang="lat">maiestas</procedure>
trial for seditious behavior as tribune.</p>
</en></p>
</charge>
]]></richtext></data>
</xf:instance>
Like the XML form, the serialized form of an instance document is represented in two different ways at different moments:
- in a running instance of a form being delivered with XSLTForms, it's represented as a string of characters which conforms to XML syntax rules.
- In the XHTML+XForms document itself, it's represented as an escaped string.
Moving back and forth
editIf TinyMCE is to be used on a document instance (or part of an instance) which has a normal XML structure, then it will be necessary to serialize the document. The serialize()
function is helpful here. After the user has edited the serialized version of the data, if it is desired to restore its normal XML structure, the serialized data must be reparsed; the xf:setnode
extension element is useful for this purpose.
[Example needed, showing movement back and forth from normal form to serialized form.]
Styling the control
editThe XForms rich-text control can be styled in the usual way for XSLTForms.
For example, the following style
element sets the font family, height, and width for textarea controls within an element of class large-textarea
.
<style type="text/css">
.large-textarea textarea {
font-family: Courier, sans-serif;
height: 10em;
width: 500px;
}
</style>
The actual XForms control can then be linked to this style simply by assigning it to the class large-textarea
:
<textarea ref="richtext"
class="large-textarea"
mediatype="application/xhtml+xml"/>
For more information on styling controls in XForms, see this wikibook's discussion of CSS.
Customizing the TinyMCE editor
editThe basic mechanism for customizing TinyMCE is the initialization object. This is a user-specified Javascript object which TinyMCE consults during initialization.
In the TinyMCE documentation, this is shown as the function argument in a call to the TinyMCE init()
function. Examples in the TinyMCE documentation may look something like the example below; this shows a simple initialization object with the properties selector
and toolbar
.
<script>
tinymce.init({
selector: '#mytextarea',
toolbar: 'undo redo | bold italic | bullist'
});
</script>
In XSLTForms, the call to the TinyMCE init()
function is handled by XSLTForms, not by the XForm author. So the initialization object is specified not in the call to init()
but as the character content of the xsd:appinfo
element in the simple type to which the element to be edited is bound. In the XSLTForms context, the selector
property is not used (if supplied, it is ignored, overwritten by XSLTForms), so the equivalent of the initialization object shown above will look something like this (the surrounding schema is not shown):
<xsd:appinfo> {
toolbar: 'undo redo | bold italic | bullist'
} </xsd:appinfo>
The following subsections describe a few simple customization examples, but for full information on the possible ways of customizing TinyMCE, see the documentation for the version of TinyMCE you are using. (The examples here use TinyMCE 4.)
With a few exceptions, every initialization property described by the TinyMCE documentation can be specified within the xsd:appinfo
element and XSLTForms will pass its value through to TinyMCE, so the effect will be as described by the TinyMCE documentation.
The exceptions are these:
- The
location
property (stressed heavily by the TinyMCE documentation, because required by TinyMCE) is supplied by XSLTForms, based on the type bindings of the data. Anylocation
value passed in by the user will be overwritten with an ID generated by XSLTForms for the particular control instance being initialized.
- The
mode
property (which doesn't seem to be described by the TinyMCE documentation, but may be used in aneditor.setMode()
call) is overwritten by XSLTForms with the value"none"
.
- The
setup
property (whose value is a function, which TinyMCE evaluates during initialization of an editor instance) is supplied by XSLTForms. Anysetup
value passed in by the user will be overwritten. TinyMCE customizations which require use of thesetup
property, including the specification of custom buttons, are thus not possible. For a workaround, see the discussion of custom buttons, below.
Styling elements within the TinyMCE editor
editA stylesheet to be used for the display of elements within the TinyMCE editor can be supplied by giving its URI (relative to the location of the XForm) as the value of the 'content_css' property in the TinyMCE initialization object. For example:
content_css: 'mce-control.css'
Setting the toolbar, menus, etc.
editThe toolbar
property can be used to specify what goes in the toolbar; it is helpful for eliminating unwanted tools in order to have a simpler interface.
'Custom' elements and 'valid' elements
editTinyMCE makes an effort to produce clean HTML, and to allow users of the TinyMCE library to constrain the HTML further.
If the initialization object specifies a list of valid_elements
, other elements in the data will be stripped out when the data are cleaned up (this happens before data are sent back to XSLTForms, as well as at other times). So valid_elements
can be used to restrict the data being edited to a specified set of elements.
Non-XHTML elements can also be specified, in the custom_elements
property.
XML elements not in XHTML
editIn a typical XForms application, the XML being edited is not necessarily XHTML; elements with names not known from the XHTML spec can be supported, by specifying their names as the value of the custom_elements
property.
[It appears to be necessary to specify custom elements both in the custom_elements
property and in the valid_elements
property. Testing for further information would be a good idea.]
It is also possible to specify what elements are allowed as children of a particular element. During data cleanup, TinyMCE may restructure the data if it thinks an element present in the data is not legal as a child of its parent. [Further details needed.]
Surprises, complications, problems
editVersioning issues
editWhere to find TinyMCE, where to put TinyMCE
editFor some time, XSLTForms has shipped with TinyMCE version 3.4.6; the code is placed within the XSLTForms directory at the location scripts/tinymce_3.4.6/tiny_mce.js
. When other versions of TinyMCE are used, it is convenient to download the minimized version from the TinyMCE web site and install it in an appropriately named subdirectory of scripts
. Other locations may also work.
TinyMCE has changed somewhat since version 3.4.6; some changes involve look and feel (TinyMCE 3 looks dated compared to 4), others involve the API.
Which versions of TinyMCE does XSLTForms support?
editXSLTForms 638 supports both version 3 and version 4 of TinyMCE; the minimal example of TinyMCE given on the AgenceXML web site uses TinyMCE 4.0.28. But not all versions of TinyMCE 4 appear to work with XSLTForms version 638; the most recent version that does appear to work is 4.3.12 (of May 2016). Later versions produce a "Loading..." message which never goes away, and an error message on the Javascript error console.
N.B. It is currently expected that release 640 of XSLTForms will support the most recent version of TinyMCE, 4.5.3.
Custom buttons
editThe addButton()
method
edit
To define custom buttons for the editor, the TinyMCE documentation suggests calling the addButton()
method on the TinyMCE editor object; the argument to the method is an object specifying a button identifier, a button label or icon, a function to run when the button is clicked, etc.
The TinyMCE documentation gives as an example:
editor.addButton('mybutton', {
text: "My Button",
onclick: function () {
alert("My Button clicked!");
}
});
The setup()
callback function
edit
An obvious first complication is that the editor object in question is not available until the TinyMCE init()
function is called. So the code shown above cannot simply be placed in a script
element in the page. Instead, the user supplies a callback function to TinyMCE, to be executed as part of initialization. (Some readers may know callback functions under other names like hooks or user exits.) The user does this by supplying the function as the value of the setup
property in the TinyMCE initialization object; the setup()
function gets one argument, the editor object.
<xsd:appinfo> {
// other properties here ...
setup: function(editor) {
editor.addButton('mybutton', {
text: "My Button",
onclick: function () { alert("Clicked!");
});
}
} </xsd:appinfo>
Button actions
editIn practice, other issues may arise. If the purpose of the button is to do for a custom phrase-level element what the builtin bold
and italic
buttons do for the HTML strong
and em
elements, then first the custom elements need to be declared and made valid, using the custom_elements
and valid_elements
properties described above.
Second, there must be functions to perform the action desired when the button is clicked. As is shown above, the function should take no arguments. In order to interact with the editor, therefore, we need to declare the function in a context where the TinyMCE editor object is available: namely, inside the setup()
function, where the editor object is passed in as an argument.
An example
editSuppose that we want to tag the currently selected text with a custom element, i.e. insert a start-tag before the current selection and an end-tag after it. To reduce redundancy in the code, we can define this with a generic Javascript function that takes the element type name as an argument, and any number of element-specific functions which call the generic function:
function insertElem(gi) {
var s = '<' + gi + '>'
+ editor.selection.getContent()
+ '</' + gi + '>';
editor.insertContent(s);
}
function insertPerson () { insertElem('person'); }
function insertProc () { insertElem('procedure'); }
Putting everything together into the initialization object, we get an appinfo
element like the following:
<xsd:appinfo> {
// other properties here ...
// adjust toolbar to taste, but don't forget to add the custom buttons
// 'insertperson' and 'insertprocedure'
toolbar: 'undo redo | insertperson insertprocedure italic | bullist',
custom_elements: "charge,~person,~procedure,en",
valid_elements: "charge,p,i,person[pid],procedure[pid],en",
setup: function(editor) {
function insertPerson () { insertElem('person'); }
function insertProc () { insertElem('procedure'); }
function insertElem(gi) {
var s = '<' + gi + '>'
+ editor.selection.getContent()
+ '</' + gi + '>';
editor.insertContent(s);
}
editor.addButton('insertperson', {
text: "Person",
onclick: insertPerson,
tooltip: "Insert person element"
});
editor.addButton('insertprocedure', {
text: "Procedure",
onclick: insertProc,
tooltip: "Insert procedure element"
});
}
} </xsd:appinfo>
Necessary modifications to XSLTForms 638
editThe remaining complication is that while the initialization object just shown will work with TinyMCE, by default XSLTForms overwrites the user-supplied setup
property with its own setup function.
To allow both the standard XSLTForms setup and the user-supplied setup to be executed by TinyMCE, three changes are needed in the code of xsltforms.js version 638 (applicability to other versions cannot, of course, be guaranteed). All three changes occur in the definition of a function named XsltForms_input.prototype.initInput
. In XSLTForms 638, this is easily found by searching for the string "setup
", which appears only in that function.
N.B. It is currently expected that release r640 will include the patch, or an equivalent patch, so the changes described here will be unnecessary.
1. After the line reading initinfo.mode = "none";
, insert the lines
initinfo.Xsltforms_usersetup =
(initinfo.setup
? initinfo.setup
: function (ed) {} );
This defines a property named Xsltforms_usersetup
(the name is chosen to minimize the likelihood of conflict with any new properties in future versions of TinyMCE), whose value is the user-supplied value of the setup
property, if there is one, and otherwise a vacuous function which does nothing.
2. Immediately following, there is a conditional testing for TinyMCE version 3.*; each branch of the if/then/else assigns a value to the setup
property.
In the then
branch, change the function by inserting a call to initinfo.Xsltforms_usersetup()
. Replace
initinfo.setup = function(ed) {
ed.onKeyUp.add(function(ed) {
...
});
ed.onChange.add(function(ed) {
...
});
ed.onUndo.add(function(ed) {
...
ed.onRedo.add(function(ed) {
...
});
};
with
initinfo.setup = function(ed) {
/* user exit for setup() */
initinfo.Xsltforms_usersetup(ed);
ed.onKeyUp.add(function(ed) {
...
});
// etc.
...
};
3. In the else
, do the same thing. For
initinfo.setup = function(ed) {
ed.on("KeyUp", function() {
...
});
ed.on("Change", function(ed) {
...
});
ed.on("Undo", function(ed) {
...
});
ed.on("Redo", function(ed) {
...
});
};
substitute
initinfo.setup = function(ed) {
/* user exit for setup() */
initinfo.Xsltforms_usersetup(ed);
ed.on("KeyUp", function() {
...
});
... etc. ...
};
With these changes, it becomes possible to define custom buttons for the XSLTForms mixed content control using TinyMCE.
Performances
Performance and optimization
editWhere does the time go?
editThe first step in dealing with any performance problem is to measure the form and see where the time is going.
XSLTForms includes a built-in profiler and debugger, which can be made visible by including the processing instruction <?xsltforms-options debug="yes"?>
at the top of your document, or (normally) by pressing F1 in a desktop browser. At the top of the screen, the label "Debug mode" will appear, together with version information and the reminder "Press F1 to toggle mode." Below the "Debug mode" heading two buttons will appear, labeled "Profiler" and "Trace log".
Clicking on the "Profiler" button will cause a time profile for the form to be opened in a new tab or window. Among other things it will show the cumulative time spent evaluating all the XPath expressions in the form. In some cases, a very small number of expressions consume a large percentage of the evaluation time; the profiler allows optimization effort to be concentrated where it will do the most good.
[Some general advice on optimization would be useful here. Use subforms, exploit locality, etc.]
Does running the XSLT transform in the client slow things down?
editTests and performance measurements show that the XSL transformation time is very short, whatever the browser.
The time to initialize the structures of the XPath interpreter and processing of interactions with the user depends on the performance of the browser's JavaScript engine.
Some results here: http://www.web21th.com/samples/performances.htm [No longer available, February 2017]
These tests were made in May 2009, with some modifications in XSLTForms source in order to introduce probes.
XForms 1.1
This page discusses XSLTForms' coverage of the XForms 1.1 specification, and mentions some other restrictions that may not be obvious to new users.
(In its current state the page is not at all complete or systematic, but a list of things that have caught the eye of some user or other, who has listed them here. Please help make the list more complete and more useful to new users of XSLTForms, by recording here any limitations you encounter and ways to work around them.)
XSLTForms implements most of XForms 1.1 but is not a fully conformant processor, for two reasons:
- Some restrictions are imposed on XSLTForms by client-side limitations in Web browsers.
- Lack of time has led to the omission of some "minor" features in favor of extension functionality with higher priority for users (e.g. rich-text editors).
The sections below identify particular points on which XSLTForms may differ from the specification or from other implementations of XForms 1.1. The sections correspond to the organization of the XForms 1.1 spec and test suite; some headings have been changed for clarity. Unless otherwise specified, the version described is 1.0RC2 (2014). Some gaps may have been filled, and some limitations removed, in later versions. (This has been noted in some cases, but the absence of a note does not mean there has been no change.)
A fuller sense of current gaps in coverage can be obtained by looking at the XForms 1.1 test suite results for XSLTForms. (Warning: that page is updated only infrequently and is not necessarily current.)
Differences between XForms 1.0 and XForms 1.1
editIntroduction to XForms
editDocument Structure
edit- In XSLTForms, the XHTML
src
attribute cannot be used to link to non-XML page-external resources. So XSLTForms does not support constructions like<xf:label src="mylabel.txt"/>
; the XSLT 1.0 processors in browsers cannot read non-XML resources. - XML comments in instance are supported but they should not contain any greater-than signs (>).
- The XForms spec allows the
xf:instance
to be omitted entirely from the model; a very simple flat XML structure is then assumed. XSLTForms requires an explicit instance.
- [This was true in 2010; is it still true, or has the 'simple XForm' structure been implemented? Tests needed. Note that XSLTForms 1.0RC2 passes test 3.3.2.a.]
Processing Model
edit- XSLTForms can load at most one external schema document per namespace; attempts to load multiple schema documents for the same namespace will raise an XForms link exception.
- XSLTForms does not implement support for the
navindex
oraccesskey
attributes. - In XSLTForms, event handling sometimes deviates from the letter of the spec. Cases include the following.
- Some tests written to trigger an
xf:message
action when particular events occur do not in fact display a message. The events in question include: xforms-help and xforms-hint; in-range, out-of-range; scroll-first, scroll-last, xforms-binding-exception; xforms-enabled, xforms-disabled. (It is not clear from the test results whether this is a problem is a failure to raise the expected events or a failure of the xsl:message action to respond to them as expected.)
- Some tests written to trigger an
- N.B. in version r638, some of these tests produce the expected results, including tests for: scroll-first, scroll-last, xforms-binding-exception.
- In some tests, XSLTForms does not raise the expected exception but a different one.
- In some tests, errors in the form which should raise exceptions (e.g. xforms-compute-error or xforms-binding-error) raise none. (In later testing with version r638, XSLTForms passes these tests.)
- Some exceptions should be fatal errors but are not, in XSLTForms.
- In some cases, the browser freezes instead of XSLTForms raising the expected exception or a fatal error.
- Some events are signaled even when
incremental="false"
entails that they should not be, or when they are unnecessary because a value has not changed.
Datatypes
edit- The built-in datatypes gYear, gYearMonth, date, and dateTime support only four-digit years beginning with the digit 1 or 2, so dates like (for example) 0800-12-25 (Christmas Day, AD 800, Charlemagne crowned emperor) are not accepted.
- gYear, date, etc. do not accept time-zone information, so a date like 2010-08-01 (1 August 2010) is accepted as valid, but not 2010-08-01Z (the 24-hour period beginning at 00:00 on 1 August 2010 in UTC) or 2010-08-01-04:00 (the 24-hour period beginning at 00:00 on 1 August 2010 in Eastern Daylight Time).
Model Item Properties
edit- The XForms spec says that "It is an error to attempt to set a model item property twice on the same node"; this can be read as allowing different model item properties to be set on a node from different
bind
elements. XSLTForms raises an error if more than onebind
element affects the same node, even if they are setting different model item properties. (Workaround: set all model items properties for any node in a singlebind
element.) - The
p3ptype
property is not implemented.
XPath Expressions in XForms
edit- XPath allows whitespace between tokens (so
a/b/c[@x='y']
anda /b /c [@x = 'y']
are equivalent, and the blanks in the latter form can be replaced by newlines and more whitespace); the XPath parser in XSLTForms accepts whitespace only in very restricted locations, including predicates, but not within location paths. [This limitation may have been lifted in 2016; tests needed.] - XSLTForms 1.0RC2 does not support the hmac() function, or the use of sha-256 in the digest() function. (Later versions support both).
- In some cases, XSLTForms calculates the wrong context size.
- XSLTForms is sometimes laxer in type validation that the spec prescribes.
- No error is raised when a
textarea
control is bound to an element with a complex type. (Instead, the string value of the element is made available for editing in the control.) - No error is raised when the parameters of a control do not obey the data binding restrictions.
- No error is raised when a
Unrecognized namespace prefixes
editIn some circumstances, XSLTForms will fail to evaluate XPath expressions correctly because it fails to recognize a namespace prefix, even though it has been correctly declared. The circumstances are:
- XSLTForms is running in Firefox or another Mozilla-based browser.
- The namespace prefix is not used on any element or attribute in the form itself. This may occur if the instance document using the namespace is external, and an XPath expression in the form refers to elements in that instance document.
The cause of this behavior is that the Mozilla XSLT engine does not support the namespace
axis; this has been reported as a bug, but has not been fixed.
A simple workaround is to insert a dummy element or attribute somewhere in the XForm which uses the namespace prefix in question. It is not uncommon to place these on the first tag of the XForms document, together with namespace declarations for all prefixes to be used in the document. (Making an XForms template with a relatively complete set of namespace declarations saves a good deal of debugging time later.)
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xsd:dummy="Help the poor user of Mozilla evade the Mozilla namespace curse"
xhtml:dummy="Help the poor user of Mozilla evade the Mozilla namespace curse">
The local name and value of the dummy attribute are immaterial; the purpose of including the dummy attribute is to ensure that XSLTForms can create a table of namespace prefixes by traversing the ancestors of an element and noting all the namespace prefixes actually in use.
For longer examples see the wikibook XSLTForms and eXist and the discussion of user-defined functions in this wikibook.
Core Form Controls
editmediatype
is not supported on file uploads.- Both
start
andend
attributes are required, not optional, onrange
controls in XSLTForms. Theincremental
attribute does not work as expected. - On the
xf:help
,xf:hint
, andxf:alert
elements, XSLTForms does not support theref
attribute. When multiple hint or alert messages are provided, XSLTForms assigns precedence to inline messages, rather than hints in the instance pointed to by single node binding attributes. - When the
xf:setfocus
action is called to set the focus to a group, the focus is not set to the first control in the group; focus is cleared. - XSLTForms 1.0RC2 does not support the
startindex
ornumber
attributes of therepeat
element.
The output
Element
edit
- The
output
control supports the valuesapplication/xhtml+xml
,image/svg+xml
, andimage/*
for itsmediatype
attribute. - The control is implemented in Javascript using the
.innerHTML
property of DOM nodes. application/xhtml+xml
can also be used for HTML tag soup (XSLTForms does not check whether the content is valid or not)- The content is treated as serialized (X)HTML, i.e. just text (not CDATA) from the XML point of view, to be serialized with < and > entities for tags
- To be displayed with tags, an instance element has to be serialized with the XPath function
serialize(node)
.
The upload
Element
edit
The upload
control has historically been difficult for XSLTForms to support (the very first message to the XSLTForms support mailing list was about gaps in the support of upload
. The XForms specification for the control requires more functionality than the AJAX libraries used by XSLTForms readily provide.
[Some discussion of using xf:upload, what does work out of the box and what doesn't, needed here or in separate page.]
A modified version of XSLTForms that supports the "form-data-post" submission method is available (February 2017) at https://github.com/Conal-Tuohy/Muscovy/tree/master/xsltforms
Container Form Controls
edit- The attributes repeat-model repeat-bind, repeat-nodeset, repeat-startindex, and repeat-number do not behave as expected.
- The
xf:copy
element does not behave as expected.
XForms Actions
edit- Events do not always behave as specified (see Processing Model, above).
- Resets and updates may be deferred instead of executed immediately; tests of various attributes on the
insert
anddelete
actions sometimes work as expected and sometimes not.
The XForms Submission Module
edit- Several attributes of the
xf:submission
element are not supported:indent
,encoding
,standalone
,cdata-section-elements
,invalid
,separator
. - A number of features of the XForms submission module cannot be supported owing to cross-domain restrictions in the browser.
Insert and Delete Action Patterns for Data Mutations
editXForms and Styling
edit- The CSS pseudo-classes
enabled
anddisabled
are supported; other pseudo-classes (required
,optional
;valid
,invalid
;read-only
,read-write
;out-of-range
,in-range
) are not supported. - The CSS pseudo-elements
value
,repeat-item
,repeat-index
are not supported.
See also the chapter on XSLTForms and CSS.
Complete XForms Examples
edit- XSLTForms does not support SVG as the host document language.
XForms 2.0
XSLTForms is supporting extensions of XForms 1.1 World Wide Web Consortium recommendation which are planned to be specified in the next specifications of XForms.
Details
editThe function
element of XForms 2.0 appears not yet to be supported in XSLTForms as of February 2017 (but XSLTForms does have support for user-defined functions, which can be defined in Javascript and added to the registry of XPath functions so they can be called from within XPath expressions.)
References
edit- Draft spec of XForms 2.0
- XPath Expressions Module for XForms 2.0
- XForms community group main page (links to all modules currently under development)
XForms 2.0/"dialog" element
Presentation
edit"dialog" element allows to show and hide controls in a popup approach.
A dialog is a container control with a mandatory @id attribute. It can be placed anywhere in the (X)HTML body element, considering that it will be transformed as a disabled (or hidden) DIV element by the XSLT step of XSLTForms.
A dialog is rendered using z-index property in a modal popup, with another DIV element covering all the main elements, with a lower z-index value, to disable interaction with controls. When changing controls values in a dialog, all other controls can be refreshed whether they are in this dialog or anywhere else. Label is not yet supported by XSLTForms and there is no X trigger.
Dialogs can be nested. Ancestor dialogs are masked automatically, changing the z-index property of the covering DIV.
Two actions are defined for dialogs management:
- "show": this action will enable the dialog identified by the @dialog attribute value
- "hide": this action will disable the dialog identified by the @dialog attribute value
Usually, for each dialog, there should be, at least, one trigger for showing (opening) it and another, in itself, for hiding (closing) it.
Sample Program
edit<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events">
<head>
<title>Contact</title>
<style type="text/css">
#details {
width: 250px;
height: 100px;
}
</style>
<xf:model>
<xf:instance xmlns="">
<contact>
<email/>
<firstname/>
<lastname/>
</contact>
</xf:instance>
<xf:bind ref="email" type="xf:email"/>
<xf:setfocus ev:event="xforms-ready" control="email"/>
</xf:model>
</head>
<body>
<xf:dialog id="details">
<xf:input id="firstname" ref="firstname">
<xf:label>First Name : </xf:label>
</xf:input>
<br/>
<xf:input ref="lastname">
<xf:label>Last Name : </xf:label>
</xf:input>
<br/>
<xf:trigger>
<xf:label>Close</xf:label>
<xf:action ev:event="DOMActivate">
<xf:hide dialog="details"/>
<xf:setfocus control="email"/>
</xf:action>
</xf:trigger>
</xf:dialog>
<xf:group>
<xf:label>Contact Information</xf:label>
<xf:input id="email" ref="email" incremental="true">
<xf:label>E-mail : </xf:label>
</xf:input>
<xf:trigger>
<xf:label>Details</xf:label>
<xf:action ev:event="DOMActivate">
<xf:show dialog="details"/>
<xf:setfocus control="firstname"/>
</xf:action>
</xf:trigger>
</xf:group>
</body>
</html>
References
edit- W3C XForms WG Wiki - Dialog candidate specifications for XForms 1.2
- AJAXForms Addons - Specific dialog addon
- Orbeon Dialog Extension
XForms 2.0/var element
Description
editThe xf:var
element declares a local variable and binds a value to the variable; the value is calculated from the value
attribute if present, and otherwise from the content of the var
element. The variable thus declared is in scope for all following siblings of the var
element and for their descendants.
Syntax
editvar name="name" value="/exampleNode"
Examples
edit[to be supplied]
Known limitations
editCurrent versions of XSLTForms [February 2017] appear to have some difficulties with references from expressions on nested xf:repeat
elements.
Further information
edit
XForms 2.0/XPath 2.0 Functions
XPath 2.0 and 3.0 functions
editXPath 2.0 and 3.0 functions supported by XSLTForms (alphabetical order):
[Some description of XPath 2.0 item-type declarations possibly needed here, to explain the signatures ...]
- distinct-values($heap as xs:anyAtomicType*)
- ends-with($haystack as xs:string, $needle as xs:string)
- format-number($value as numeric?, $picture as xs:string)
- lower-case(nodeset?)
- replace($input as xs:string, $pattern as xs:string, $replacement as xs:string)
- string-join($bricks as xs:string*, $glue as xs:string)
- tokenize($input as xs:string, $pattern as xs:string)
- upper-case(nodeset?)
Also the mathematical functions abs, acos, asin, atan, atan2, cos, exp, log, power, random, sin, sqrt, and tan. [Signatures to be supplied.]
N.B. this list is complete as of version r638.
There are a number of XPath 2.0 functions that have not yet been implemented in r638.
XForms 2.0 functions
editN.B. This list does not include functions that were already defined in XForms 1.1.
XSLTForms has (as of r638) implemented these:
- serialize()
These are apparently not yet implemented in XSLTForms (as of r638) (in alphabetical order): attribute(), bind(), case(), element(), eval(), eval-in-context(), location-param(), location-uri(), parse(), readonly(), relevant(), required(), seconds-from-dateTime(), seconds-from-epoch(), seconds-to-dateTime(), uri-authority(), uri-fragment(), uri-host(), uri-param-names(), uri-param-values() , uri-path(), uri-port(), uri-query(), uri-scheme(), uri-scheme-specific-part(), uri-user-info().
XSLTForms only Extensions
Configuration
editConfiguration options affecting the XSLTForms transformation are taken from the sources below,
where the value for each option is the one found first:
- externally-defined XSLT Parameters,
- config_LANG.xsl file,
- Processing-Instructions(PIs).
XSLT Params
editUnder the xmlns="http://www.w3.org/1999/XSL/Transform" the following xsl-params are accepted:
- baseuri: If unspecified, defaults to the base-name of the xsltforms.xsl href.
- xsltforms_caller:
- xsltforms_config: A nodeset having as child the configuration <properties> element that are to be copied on the result xforms-page. Defaults to the ones specified in config.xsl file.
- xsltforms_debug: 'yes' or anything else. If unspecified, assumed no-debug.
- xsltforms_lang: The suffix to use when selecting the language file config_<SUFFIX>.xsl which specifies messages, calendar and other localizations/I18Ns.
Note that xsltforms_config, xsltforms_debug, xsltforms_lang params are further applied to any subsequent transformations of documents containing a xsl-stylesheet PI, either on submission with replace="all" or SVGs, or when applying the transform() extension function.
Config File: config.xsl
editSample configuration file:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template name="config">
<options>
<nocss><!-- When existent, no css-conversion hapens. -->
</options>
<properties> <!-- Accessible at run time from within model('xf-model-config')/instance('xf-instance-config'). -->
<language>navigator</language> <!-- navigator or default -->
<calendar.day0>Mon</calendar.day0>
<calendar.day1>Tue</calendar.day1>
<calendar.day2>Wed</calendar.day2>
<calendar.day3>Thu</calendar.day3>
<calendar.day4>Fri</calendar.day4>
<calendar.day5>Sat</calendar.day5>
<calendar.day6>Sun</calendar.day6>
<calendar.initDay>6</calendar.initDay>
<calendar.month0>January</calendar.month0>
<calendar.month1>February</calendar.month1>
<calendar.month2>March</calendar.month2>
<calendar.month3>April</calendar.month3>
<calendar.month4>May</calendar.month4>
<calendar.month5>June</calendar.month5>
<calendar.month6>July</calendar.month6>
<calendar.month7>August</calendar.month7>
<calendar.month8>September</calendar.month8>
<calendar.month9>October</calendar.month9>
<calendar.month10>November</calendar.month10>
<calendar.month11>December</calendar.month11>
<format.date>MM/dd/yyyy</format.date>
<format.datetime>MM/dd/yyyy hh:mm:ss</format.datetime>
<format.decimal>.</format.decimal>
<status>... Loading ...</status>
</properties>
<extensions>
<!-- JS script code to add.
- When none of the following child elements exist, any elements here are copied
- just after xsltforms.js and before init-scripts.
-->
<beforeInit/> <!-- Added in a separate <script> element, after xsltforms.js and before init-scipts. -->
<onBeginInit/> <!-- Added within init-code <script> at the beginning of initImpl() function, before any definitions. -->
<onEndInit/> <!-- Added within init-code <script> at the end of initImpl() function, after xforms.init() invocation. -->
<afterInit/> <!-- Added in a separate <script> element, after init-scripts. -->
</extensions>
</xsl:template>
</xsl:stylesheet>
Processing Instructions
editA xforms page can specify the following processing-instructions(PI) that act as configuration parameters:
- xsltforms-options: It accepts 2 pseudo-attributes, sample:
<?xsltforms-options debug="yes" lang="en"?>
- css-conversion: sample:
<?css-conversion no?>
Elements
edit- xforms:tree: content-model: (xforms:label?, xforms:item/xforms:label*)
- xforms:setnode: accepts ref attribute to bind a node, inner or outer attribute whose value is an XML serialization of one or more XML nodes; the inner or outer attribute is parsed, and the resulting nodes replace either the children of the node bound by ref, or the node itself. (See separate page for setnode.)
Functions
editExtension functions supported by XSLTForms:
- is-valid(nodeset?): returns true when all nodes in the nodeset are valid.
- transform(nodeset, xslt-href): transforms the node from the node-set which is first in document order using the specified xslt, see https://sourceforge.net/mailarchive/forum.php?thread_name=4BB26785.4070807@agencexml.com&forum_name=xsltforms-support
- serialize(nodeset?): serializes the node from the node-set which is first in document order into string(??)
User-Defined Functions
editHere is a sample of how to define user-defined XPath functions:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="xsltforms/xsltforms.xsl" type="text/xsl"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:nfunc="http://example.net/xforms/new-functions/"
nfunc:bogus="Workaround for FF's bug: https://bugzilla.mozilla.org/show_bug.cgi?id=94270"
>
<head>
<title>User-Defined XPath functions</title>
This is for old versions of XsltForms:
<script>
XPathCoreFunctions['http://example.net/xforms/new-functions/ new-func'] =
new XPathFunction(
false, /* is accepting context as 1st-arg? */
XPathFunction.DEFAULT_NONE, /* context-form as 1st-arg, when (args.length == 0): [ DEFAULT_NONE | DEFAULT_NODE | DEFAULT_NODESET | DEFAULT_STRING ] */
false, /* is returning nodes? */
function() {
return "NEW FUNC";
}
);
</script>
This works for new versions of XsltForms:
<script>
XsltForms_xpathCoreFunctions['http://example.net/xforms/new-functions/ new-func'] =
new XsltForms_xpathFunction(
false, /* is accepting context as 1st-arg? */
XsltForms_xpathFunction.DEFAULT_NONE, /* context-form as 1st-arg, when (args.length == 0): [ DEFAULT_NONE | DEFAULT_NODE | DEFAULT_NODESET | DEFAULT_STRING ] */
false, /* is returning nodes? */
function() {
return "NEW FUNC";
}
);
</script>
</head>
<body>
<p>
Hello to <xf:output value="concat('My ', nfunc:new-func())" />.
</p>
</body>
</html>
Notice the attribute on <html> element required for working under Firefox:
nfunc:bogus="Workaround for FF's bug: https://bugzilla.mozilla.org/show_bug.cgi?id=94270"(feel free to vote for this mozilla-bug to get fixed some day...) |
Arithmetic expressions
editObjects in the javascript: pseudo-URL in xf:load/xf:resource@value
editWhen the javascript: pseudo-URL is used within the xf:load/xf:resource@value attribute, the id of the enclosing <xf:load> element is contained by the following js object-property:
XSLTFormsContext.elementId
Using TinyMCE as mixed-content editor
editSee separate page on this topic.
component
[Full description to be supplied. In the meantime, follow the reference link. The entire thread of which it is a part is worth reading.]
Description
editSyntax
editExamples and uses
editKnown problems and limitations
editFurther information
edit- [https://sourceforge.net/p/xsltforms/mailman/message/30923296/ Alain Couthures to xsltforms-support, 1 June 2013 Experimental Component control (Was: A couple of questions about subforms)
include
Description
editThe xf:include
element includes external files in a form at compile time, during the evaluation of the xsltforms.xsl
stylesheet. It is thus similar in functionality to general entities in XML, or to the XInclude xi:include
element.
It can be used to reduce duplication of code at multiple points in a form, to share code between forms, or just to move a complex part of a subform into a separate document to make the logic of the main form clearer and easier to follow.
Syntax
editThe xf:include
element is empty. It carries just one attribute: src
.
The value of the src
attribute is a URI reference (absolute or relative) pointing to an XML document to be included in the form.
Examples
editRepeated code within a form
editConsider an XForm which accepts query data from a user, submits a query to a back end search engine, and displays the results to the user. To avoid overloading the user's browser and/or the network, we wish to send only a page's worth of results to the user at any one time, and allow the user to page through the results, so-and-so many results at a time.
The general outline of such a form might be something like this; we assume an instance named query
to hold the query string and the starting position within the results, and an instance named results
to hold the results.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events">
<head>
...
</head>
<body>
<h2>Query tool</h2>
... controls for query string, submission ...
<xf:group ref="instance('results')/self::result[.//hits]">
... code for Back and Forward buttons ...
<xf:repeat nodeset="self::test//hits/hit">
... display one hit ...
</xf:repeat>
... code for Back and Forward buttons ...
</xf:group>
</body>
</html>
To reduce the need for scrolling up and down in the results page, we wish to have buttons for moving forward and back in the results both at the top of the results list and at the bottom. The code will be the same for both: first a Back button, which displays only if the current starting position is greater than 1:
<xf:group ref=".[instance('query')/startpos > 1]">
<xf:trigger>
<xf:label>Back</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('query')/startpos"
value="instance('query')/startpos - instance('query')/pagesize "/>
<xf:send submission="send-query"/>
</xf:action>
</xf:trigger>
</xf:group>
Then a message indicating location in the results (e.g. "11 to 20 of 34", or "No results"):
<xf:group ref=".[.//hits/@n > 0][.//hit]">
<p>Results <xf:output ref=".//hit[1]/@n"/>
to <xf:output value=".//hit[last()]/@n"/>
of <xf:output value="instance('results')//hits/@n"/>
</p>
</xf:group>
<xf:group ref=".[.//hits/@n = 0]">
<p>No results.</p>
</xf:group>
And finally a Forward button, which displays only if we are not currently displaying the last hit:
<xf:group ref=".[(instance('query')/startpos + count(.//hit))
<= (self::test/results/hits/@n)]">
<xf:trigger>
<xf:label>Forward</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('query')/startpos"
value="instance('query')/startpos + instance('query')/pagesize"/>
<xf:send submission="send-query"/>
</xf:action>
</xf:trigger>
</xf:group>
Note that the forward and back buttons, and the current-location message, have no IDs that need to be unique; there is no problem including their text twice in the form. To make that happen, we must
- Make an XML document containing the Back button, the location message, and the Forward button. We wrap these three elements in an XHTML
div
element to give the XML a single root element, and call the result file "FBButtons.xhtml". - In the appropriate locations in the main form, use the
xf:include
element with the appropriatesrc
value. If "FBButtons.xhtml" was placed in the same directory as the main form, we'll use<xf:include src="FBButtons.xhtml"/>
.
Known problems and issues
edit- The
xf:include
element works as specified in the main XForm, and recursively in documents loaded viaxf:include
. In subforms, which are loaded later, it works in some browsers but not in others (including Webkit-based browsers). Cause of this discrepancy is the unwillingness of some browsers to evaluate the XSLTdocument()
function in XSLT stylesheets invoked from Javascript, which is motivated by security concerns of some description.
- Browsers will enforce the same-origin policy, which means the absolute URI pointing to the XML document to be include will need to be on the same host as the form itself. [Tests and empirical confirmation of this claim would be desirable.]
For further information
edit- Alain Couthures to xsltforms-support list, 3 Jul 2016 explaining problems with use of
xf:include
in subforms. - Sample form showing use of
xf:include
in main form and in dynamically loaded subform; the latter does not work.
setnode
The xf:setnode
action is an experimental extension of XForms, helpful for updating an instance document with the output of an XSLT transformation (see the transform() function) or with the output of a mixed-content editor (see the discussion of using TinyMCE as an XForms control).
The action is indicated using the xf:setnode
element. It has three crucial attributes:
- The
ref
attribute is a single-node binding attribute which indicates the target node. - The
inner
attribute specifies the node(s) which should replace the children of the target node; its value is the serialized XML form of the nodes. - The
outer
attribute specifies the node which should replace the target node; its value is the serialized XML form of the replacement node.
The inner
and outer
attributes are mutually exclusive; one or the other must be specified, but not both. As is usual when representing serialized XML within an attribute value, the left angle brackets and ampersands in the serialized form must be escaped.
The value of the inner
or outer
attribute is parsed as XML to produce DOM nodes, and the resulting nodes replace either the children of the target node, or the target node itself.
Example
editThe following example shows a trigger which replaces an instance named input
with a new document.
<xf:trigger>
<xf:label>Generate diagram</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setnode ref="instance('input')"
outer="<doc>
<title>My document</title>
<chapter>
<p>Hello, world!</p>
</chapter>
</doc>"/>
</xf:action>
</xf:trigger>
Using setnode
with transform()
edit
A perhaps more common usage of setnode
is to update an instance with the result of running an XSLT stylesheet or a mixed-content editor, both of which return strings with the serialized-XML form of their result.
Suppose we have an input instance which the user can modify through the form, and an XSLT stylesheet (make-svg.xsl
) which can process the input instance and create an SVG diagram representing some information from the instance. To allow the user to generate a fresh diagram, we could supply a trigger specified as follows:
<xf:trigger>
<xf:label>Generate diagram</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setnode ref="instance('svg')"
outer="transform(instance('input'),'make-svg.xsl')"/>
<xf:toggle case="picture"/>
</xf:action>
</xf:trigger>
This assumes that we have an instance named svg
, where the output of the transformation should go. It also assumes that there is a switch statement somewhere with a case named picture
, which displays the generated SVG.
Achieving similar effects in standard XForms 1.1
editIn standard XForms 1.1, one way to achieve similar effects is to submit the string (the serialized XML) to a server which reflects it back unchanged, with the MIME type application/xml
(or similar), and specify that the submission updates the instance in question.
The example given above would be rewritten as:
<xf:trigger>
<xf:label>Generate diagram</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('svg')"
value="transform(instance('input'),'make-svg.xsl')"/>
<xf:send submission="parse-as-xml"/>
<xf:toggle case="picture"/>
</xf:action>
</xf:trigger>
The parse-as-xml
submission submits the string value of the svg
instance to the server, which reflects it back as XML (so the browser parses it and updates the instance normally):
<xf:submission id="parse-as-xml"
ref="instance('svg')/text()"
method="post"
resource="../lib/reflect-as-xml.sh"
replace="instance"
instance="svg"
/>
The CGI script on the server does nothing but return the submitted data, labeled as XML:
#!/bin/sh
echo "Content-Type: application/xml"
echo
cat
Achieving similar effects in standard XForms 2.0
editTo achieve similar effects in XForms 2.0, one can use the xf:insert
action, using the XForms 2.0 parse()
function in the value of the origin
attribute.
[Example needed.]
The transform function
Description
editThe transform()
function is an XSLTForms extension to the standard XForms function library. Public discussions suggest that it's based on proposals for a similar function to be included in XForms 2.0, but work seems to have stalled in 2011. There seems to be no transform()
function in the current draft of the XPath Expressions Module, and not currently active specification of a separate module for the transform()
function.
Syntax / Signature
editThe transform()
function applies an external XSLT stylesheet to a node set. In current versions of XSLTForms (since 2014 or so), it takes a series of three or more arguments:
- The first argument is a node to be transformed (e.g.
instance('foo')/bar/baz
or justchild-element
or.
). - The second argument is either
- the URI of an XSLT stylesheet, as a string (e.g.
'my-transform.xsl'
), or - a string representation of an XSLT stylesheet.
- the URI of an XSLT stylesheet, as a string (e.g.
- The third argument is
true
if the second argument is an XSLT stylesheet in string form,false
if the second argument is the URI of an XSLT stylesheet. - The fourth, sixth, eighth, ... arguments, if present, are names of XSLT stylesheet parameters.
- The fifth, seventh, ninth, ... arguments, if present, are values for those parameters.
Note: Earlier versions of the function took only two arguments: the node to be transformed, and the URI of an XSLT stylesheet.
The transform()
function returns a string. This will seem implausible to many XSLT users, so it needs to be stressed: the transform()
function returns a string.
- If the XSLT output method is
text
, the returned value is the string (wrapped, in almost all browsers under almost all circumstances, in some browser-dependent XML element). - If the XSLT output method is
xml
, the returned value is the serialized form of the XML document produced. Under most circumstances, looking at it will show the angle brackets and ampersands escaped as<
and&
. If the returned value is injected into the XHTML document, however, the results are formatted like normal HTML.
(And the html
output method?)
Examples and uses
editFormatting data in read-only form
editOne use for transform()
is to format XML instance data into appropriately styled HTML for convenient read/only display by the browser. For example:
<div style="margin: 1em 0;">
<xf:output value="transform(my-tricky-element, 'display-tricky.xsl')"
mediatype="application/xhtml+xml" />
</div>
Showing XML source
editAnother use for transform()
is to pretty-print XML instance data for convenient read/only display of the XML source by the browser. For example:
<h2>XML representation of the data</h2>
<pre style="border: 2px #552211 solid;
padding: 0.5em;
background-color: #f7eed4;">
<xf:output value="transform(instance('doc'),'../lib/prettyprint.xsl')"
mediatype="text/plain" />
</pre>
This example assumes a pretty-printing stylesheet which produces output with newlines and suitable indentation. This is not necessary in principle (one could use serialize(instance('user-data'))
instead), but useful in practice, since otherwise some browsers display the entire XML document on one very long line of output.
Updating an instance
editSince transform()
returns a string, the following attempt to generate a new document instance for further processing by XForms will fail: instead of replacing instance foo
with the output of the transformation, it will replace the content of foo
with the serialized string form of the transformation result.
<xf:trigger>
<xf:label>Generate diagram</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('svg')"
value="transform(instance('input'),'make-svg.xsl')"/>
<xf:toggle case="picture"/>
</xf:action>
</xf:trigger>
If the svg
instance contained a normal SVG document to start with, then after the trigger shown is fired, it will consist of an SVG element containing an XML-escaped SVG document as a single text-node:
<svg xmlns="http://www.w3.org/2000/svg"
width="100%"
height="100%"><svg xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
width="900"
height="1000">
<desc>SVG representation of the data</desc>
...
</svg></svg>
One workaround for this problem is to use the experimental action xf:setnode
with inner
or outer
attributes, to replace either the content of the node or the node itself:
<xf:trigger>
<xf:label>Inner</xf:label>
<xf:setnode ref="." ev:event="DOMActivate"
inner="'<item>b</item>'"/>
</xf:trigger>
<xf:trigger>
<xf:label>Outer</xf:label>
<xf:setnode ref="item" ev:event="DOMActivate"
outer="'<item>c</item>'"/>
</xf:trigger>
Another workaround is to submit the string to a script on the server which echoes it back as XML. (See the example in the discussion of the setnode
action.)
Known problems and issues
editIn Safari, and in older versions of Chrome (through version 30 and possibly later), the transformation may fail if the stylesheet whose URI is given in the second argument to transform()
contains an xsl:import
instruction. The symptom is an error alert saying TypeError: null is not an object (evaluating 'resultDocument.documentElement')
. (It's likely that this problem will also arise if the stylesheet contains an xsl:include
instruction, but that has not been verified.) This problem does not arise in Firefox, Opera, or newer versions of Chrome (from version 49 and possibly earlier).
Workaround: remove the xsl:import
, so that the stylesheet is a free-standing object without dependencies on other stylesheets.
Further information
editSome further information can be gleaned from a a set of transform() test cases which illustrate a variety of different ways to call the function and show what it produces in each case.
Additional functions
XSLTForms has implemented a number of functions beyond those required by the XForms specification. As of r638, these include:
- alert()
- control-property()
- encode-for-uri()
- fromtostep() a functional equivalent of the XPath 2.0
to
operator (1 to 10
=fromtostep(1,10,1)
) - invalid-id()
- is-valid()
- itext() (for text internationalization)
- js-eval()
- selection()
- transform()
There are separate pages for some of these. [And there should be separate pages for each of them.]
Contributing Code
The XSLTForms project has over its history moved through several source-code repositories. A Web search will find multiple SourceForge and GitHub repositories for the project.
Note: The original plan for this book was to populate the two pages linked from the table of contents with the titles XSLT 1.0 stylesheet - Templates and Javascript - Classes and Functions with auto-generated documentation for the xsltforms.xsl
and xsltforms.js
; as may be seen from the page histories, the Javascript documentation was auto-generated in 2010 and the XSLT documentation has never been generated. A new plan for providing documentation for would-be contributors may be needed.
Active repository
editCurrently (February 2017), active development takes place in a GitHub repository called xphoneforms; builds can be obtained from the repositories named xsltforms on GitHub and SourceForge but these are currently just copies from the development repository.
Proposing changes
editCurrently (February 2017), the best way to propose changes to XSLTForms is probably to use GitHub's 'pull request' feature:
- Fork the xphoneforms repository.
- Make your changes in your forked copy.
- Test them.
- Use the GitHub Make pull request button to create a pull request for the main repository which includes the changes you want to propose.
Note that the directory /src/js contains both an xsltforms.js
and an xsltforms2.js
subdirectory. If you are proposing changes to the current XSLTForms, there is no need to make changes in the latter: the two directories will be synchronized when required.
Javascript
Warning!! This documentation is automatically generated from embedded comments in Javascript sources.
XSLTForms Javascript parts are activated just after the XSLT transformation performed by the browser.
The "init()" function is created by the XSLT transformation according to the XForms document, with "xforms.init()" as the last function call, and called by the "onload" event associated with the "body" element.
Many Javascript objects and functions can be called directly by developers for specific purposes considering that misuse can compromise the XSLTForms global behavior.
Main functions and objects
edit"$" function
editShortcut for document.getElementById()
How does this work if we also want to include JQuery functions. Should a different function be used?
"Core" class
editCore class for browsers compatibility
- isOpera, isIE and isMozilla methods : return browser family
- hasClass method : tests if an element has a CSS class
- loadProperties method : AJAX method to get I18N properties
- constructURI method : construct URI according to current location
- createElement method : creates a DOM element and, optionally, add a class, attach it to its parent and fill it with a text content
- getWindowSize method : obtains window size for various browsers
- openRequest method : opens an XMLHttpRequest
"DebugConsole" class
editDebug Console Management
- write method : adds a text to the Debug Console
- clear method : clears the Debug Console
"Dialog" class
editDialog Panel Management
- show method : displays the Dialog Panel
- hide method : hides the Dialog Panel
- knownSelect method : determines whether a select control is already known by Dialog management (IE6 workaround)
- showSelects method : shows/hides the selects controls under the Dialog Panel (IE6 workaround)
"Event" class
editEvent Management
"I8N" class
editInternationalization Management
- get method : get a property value for the current language
- parse method : data parsing according to a pattern and the current language
- format method : data formatting according to a pattern and the current language
- parseDate method : direct method for date parsing
- formatDate method : direct method for date formatting
- formatNumber method : direct method for number formatting
- parseNumber method : direct method for number parsing
Miscellaneous functions
edit- forEach function : Convenient way to the same method with the same arguments to a collect of objects
- assert function : Conditional Debug Console message adding
- inArray function : Tests if a value is present in an array
- zeros function : left or right zero-padding
- getValue function : gets a node value
- setValue function : sets the value of a node
- run function : executes an action (called by generated Javascript instructions)
- getId function : gets the id of the xf element concerned by en event (FF2 compatibility problem)
- show function : show/hide an element (called by generated Javascript instructions, typically used for hints or input errors)
- trim method : left and right trim method for String class
- copyArray function : copy every element in a source array into a dest array
"xforms" class
editGlobal class for XForms Management
- init method : called from the generated init() function called at onload event
- close method : performs every closing actions
- openAction method : simply clears the Debug Console
- closeAction method : calls the closeChanges() method when every action has been performed
- closeChanges method : rebuild or recalculate after changes
- error method : XForms error management
- refresh method : XForms refresh management
- build method : XForms build management
- addChange method : builds a stack of elements concerned with changes
- dispose method : disposes of an element
- blur method : focus out management
"Binding" class
editXForms Binding Management
- constructor function : "xpath", "model" and "bind" properties are resolved
- evaluate method : evaluates the binding
"IdManager" class
editId Manager for repeat structures
XForms Model Management
editEach Model component is stored as a Javascript object created by the XSLT transformation. The XFCoreElement is the parent class for all other classes.
"XFCoreElement" class
editParent class for each Model component class
- init method : creates a "span" element under the "head" element to store this object
- dispose method : clears the properties of this object
"XFModel" class
edit- constructor function : specifically gets the associated schemas
- addInstance method : adds an instance to this model
- addBind method : adds a binding to this model
- dispose method : clears the properties of this object
- getInstance method : gets an instance of this model by its id
- getInstanceDocument method : gets the document of an instance of this model by the instance id
- findInstance method : finds the corresponding instance of a node in this model
- construct method : construct step is forwarded to instances and corresponding XForms events are dispatched
- reset method : reset action is forwarded to instances and this model is tagged as rebuilded
- rebuild method : refresh action is forwarded to instances and the "xforms-recalculate" event is dispatched
- recalculate method : recalculate action is forwarded to instances and the "xforms-revalidate" event is dispatched
- revalidate method : revalidate action is forwarded to instances and the "xforms-refresh" event is dispatched
- refresh method : no action
- addChange method : stacks this model as changed according to current step
- setRebuilded method : stores the rebuilded state according to current step
"XFInstance" class
editInstance Class
- constructor function : stores the properties of this instance and attaches it to a model
- dispose method : clears the properties and recycles the associated nodes
- construct method : loads the source of this instance locally or remotely
- reset method : simply restores the initial copy of this instance
- store method : clones the document of this instance
- setDoc method : sets a document for this instance
- revalidate method : recursively revalidates each node of this instance according to readonly and relevant attributes
"XFBind" class
editModel Binding Class
- constructor function : resolve all the properties and attach this object to the model
- refresh method : completely evaluates and refreshes this binding
- recalculate method : just recalculates this binding
"XFSubmission" class
editSubmission Class
- constructor function : store the properties of this submission and attaches it to a model
- submit method : submits serialized data according to chosen method
- toUrl_ method : recursively collects node values to add them to an URL
"XFProcessor" class
editInternal XForms Processor Class
- error function : displays an error
XForms Action Management
editEach action is stored as a Javascript object created by the XSLT transformation. The XFAbstractAction is the parent class for all action classes.
"XFAbstractAction" class
editParent class for each Action class
- init method : "if" and "while" attributes are defined in this class
- execute method : "while" attribute process calling "if" attribute process
- exec_ method : "if" attribute process calling specific "run" method
- run method : Empty method to be defined in each sub-class
"XFAction" class
editAction Class
- constructor function : specifically initializes at no child
- add method : adds a child action to this action
- run method : executes each child action of this action
"XFDelete" class
editDelete Action Class
- constructor function : resolves the properties of this delete action
- run method : executes this delete action and dispatches "xforms-delete"
"XFDispatch" class
editDispatch Action Class
- constructor function : stores specific properties
- run method : dispatches an XForms event
"XFInsert" class
editInsert Action Class
- constructor function : resolves specific properties
- run method : clones then inserts a new element and dispatches the "xforms-insert"
"XFLoad" class
editLoad Action Class
- constructor function : stores specific properties
- run method : opens a new window or changes current location according to "show" attribute
"XFMessage" class
editMessage Action Class
- constructor function : stores specific properties
- run method : displays an alert message box containing a node value
"XFSetindex" class
editSetIndex Action Class
- constructor function : resolves specific properties
- run method : sets the current index of a repeat structure
"XFSetvalue" class
editSetValue Action Class
- constructor function : resolves specific properties
- run method : sets the value of a node and records it in the changes collection
"XFToggle" class
editToggle Action Class
- constructor function : stores specific property
- run method : toggles on the associated element
- toggle method : toggles on the element according to its id and dispatches the "xforms-deselect" event
XForms Controls Management
editEach control is stored as a Javascript object created by the XSLT transformation with the id of the corresponding (X)HTML element as a property. The XFElement is the parent class for all action classes, having the XFControl class as intermediate for most of them.
"XFAVT" class
editAVT Control Class
- constructor function : initializes specific properties and initializes focus and blur event management
- clone method : creates a new output control with the given id
- dispose method : clears properties of this control and calls the parent dispose() method
- setValue method : sets the value of this AVT control
"XFElement" class
editElement Class
- constructor function : empty
- init method : initializes properties
- dispose method : clears properties of this element
- build method : abstractly builds this element from dependencies
"XFControl" class
editControl Class
- constructor function : just sets this element as a control
- initFocus method : attaches event handlers for "focus" and "blur"
- dispose method : calls the parent "dispose()" method
- focus method : manages focus and dispatches the "DOMFocusIn" event
- build_ method : specific build method updating dependencies
- refresh method : refreshes this control according to the value of the corresponding node and dispatches according events
- changeProp method : changes a property, such as required, relevant, readonly and valid, of this control
- valueChanged method : changes the value of this control and dispatches the "xforms-recalculate" event
- getXFElement function : gets the ancestor-or-self XFElement value for an element
- focusHandler function : focus handler
- blurHandler function : blur handler including a delay
"XFGroup" class
editGroup Element Class
- constructor function : sets specific properties
- clone method : creates a new group with the given id
- build_ method : specific build method
- refresh method : sets "xforms-disabled" CSS class
"XFInput" class
editInput Control Class
- constructor function : initializes specific properties including aid button management
- clone method : creates a new input with the given id
- dispose method : clears properties of this element and calls the parent dispose() method
- initInput method : initializes the input control according to its type (password/textarea/boolean/date/datetime)
- setValue method : sets the value of this input control according to its type
- changeReadonly method : changes the read only state of this input control
- initEvents method : initializes the event management according to incremental capability
- blur method : manages the blur event when not in incremental mode
- click method : manages the click event according to the input control type
- keyUpInputMode function : updates this input control value after key up
- keyUpActivate function : checks if Enter key was pressed to dispatch DOMActivate
- keyUpIncrementalActivate function : checks if Enter key was pressed to dispatch DOMActivate in incremental mode
- keyUpIncremental function : updates this input control value after key up in incremental mode
- InputMode functions set : specific check function for each possible input mode (lowerCase/upperCase/titleCase/digits)
"XFItem" class
editItem Control Class
- constructor function : initializes specific properties and initializes focus and blur event management
- clone method : creates a new item control with the given id
- dispose method : clears properties of this element and calls the parent dispose() method
- build_ method : specific build method according to label and value bindings
- refresh method : refreshes the label and the value for this item control depending whether it has a rendering as option or not
- click method : manages the click event according to the item control type
"XFItemset" class
editItemSet Control Class
- constructor function : initializes specific properties
- build_ method : specific build method with the corresponding clones creation
- refresh method : sets "xforms-disabled" CSS class
- clone method : creates a new itemset control with the given id
- refresh_ method : refreshes this ItemSet Control at a given position
"XFLabel" class
editLabel Element Class
- constructor function : initializes specific properties
- clone method : creates a new label element with the given id
- build_ method : specific build method
- refresh method : refreshes this label element
"XFOutput" class
editOutput Control Class
- constructor function : initializes specific properties and initializes focus and blur event management
- clone method : creates a new output control with the given id
- dispose method : clears properties of this control and calls the parent dispose() method
- setValue method : sets the value of this output control
- getValue method : sets the value of this output control
"XFRepeat" class
editRepeat Element Class
- constructor function : sets specific properties
- dispose method : clears properties of this element and calls the parent dispose() method
- setIndex method : sets the current index for this repeat element
- deleteNode method : deletes the given node within this repeat element and makes sure that the current index is still valid
- insertNode method : inserts the given node after another given node within this repeat element and updates the current index
- build_ method : recreates every nodes within this repeat control and sets the current index at 1
- refresh method : refreshes this repeat element and the child elements if it is not an ItemSet
- clone method : creates a new repeat element with the given id
- initClone function : initializes a clone for the given id
- selectItem function : set the current index at the given element within a repeat element
"XFSelect" class
editSelect/Select1 Control Class
- constructor function : initializes specific properties and initializes focus and change event management
- clone method : creates a new select/select1 control with the given id
- dispose method : clears properties of this select/select1 control and calls the parent dispose() method
- focusFirst method : sets focus to the first item in this select/select1 control
- setValue method : searches for the given value and checks it if found or dispatches the "xforms-in-range" event
- changeReadonly method : changes the read only state of this select/select1 control
- itemClick method : dispatches "xforms-select" and "xforms-deselect" events
- blur method : blur event management
- normalChange function : handler for normal mode on change dispatching "xforms-select" and "xforms-deselect" events
- incrementalChange function : handler for incremental mode on change calling normal mode handler
- getSelected method : collects selected options for this select/select1 control
"XFTrigger" class
editTrigger Control Class
- constructor function : initializes specific properties and initializes focus event management
- setValue method : empty
- clone method : creates a new trigger control with the given id
- click method : dispatches a "DOMActivate" event
- blur method : empty
"Calendar" class
editCalendar Class for Date/DateTime Control
- constructor function : dynamically creates a table element
- today method : sets the value of this Calendar object to the current date
- refreshControls method : refreshes this Calendar object according to a given date
- refresh method : refreshes this Calendar object
- getFirstDay method : gets the first day of the selected month
- getDaysOfMonth method : gets the number of days of the selected month
- createElement method : creates a new clickable day within this Calendar object
- show function : shows a Calendar object of a given type for a given input
- close function : hides the current Calendar object
XML Schema Management
editEach Schema is stored as a Javascript object created by the XSLT transformation. The Type is the parent class for *Type classes.
"Type" class
editType Abstract Class
- constructor function : empty
- setSchema method : associates a schema to this Type object
- setName method : associates a name to this Type object and updates the schema accordingly
- canonicalValue method : computes the canonical value according to white space management (replace, collapse)
- getMaxLength method : get the max length for this Type object or null
- getDisplayLength method : get the display length for this Type object or the max length is not defined
"Schema" class
editSchema Class
- constructor function : creates a Schema object after checking it doesn't exist yet
- all associative array : stores all schemas according to their respective namespace
- getType method : gets a type according to a given name for this schema
- getType function : gets a type according to a given prefix:name
- getTypeNS function : gets a type according to a given namespace and a given name
- get function : gets a schema according to a given namespace
- prefixes associative array : initializes default prefixes and namespaces
- registerPrefix function : adds a prefix and the corresponding namespace to the "prefixes" associative array
"AtomicType" class
editAtomicType Class
- constructor function : initializes of patterns property
- setBase method : copies the base patterns to this AtomicType object
- put method : sets the base, copies patterns or just add a property
- validate method : validates a value against this AtomicType object
- normalize method : normalizes a value for fraction digits according to this AtomicType object
"ListType" class
editListType Class
- constructor function : white space management as "collapse"
- setItemType method : associates a Type object for each item in this ListType object
- validate method : validates a value against this ListType object
- canonicalValue method : computes the canonical value of a list value
"ListType" class
editListType Class
- constructor function : initializes base types property
- addType method : adds a Type object to this UnionType object
- validate method : validates a value against at least one base type of this UnionType object
"TypeDefs" class
editDefault Type Definitions Initialization Class
- initAll method : inits the default types definitions for XML Schema and XForms
- init method : inits the default types definitions for a given namespace
- Default associative array : every default type definition for XML Schema
- base : prefix:name of the base type
- whitespace : white space behavior
- patterns : array of regular expressions
- class : associated class
- displayLength : number
- fractionDigits : number
- totalDigits : number
- minInclusive : number
- maxInclusive : number
- minExclusive : number
- maxExclusive : number
- format : formatting function
- parse : parsing function
- Predefined types :
- xsd:string
- xsd:boolean
- xsd:decimal
- xsd:float
- xsd:double
- xsd:dateTime
- xsd:date
- xsd:time
- xsd:duration
- xsd:gDay
- xsd:gMonth
- xsd:gMonthDay
- xsd:gYear
- xsd:gYearMonth
- xsd:integer
- xsd:nonPositiveInteger
- xsd:nonNegativeInteger
- xsd:negativeInteger
- xsd:positiveInteger
- xsd:byte
- xsd:short
- xsd:int
- xsd:long
- xsd:unsignedByte
- xsd:unsignedShort
- xsd:unsignedInt
- xsd:unsignedLong
- xsd:normalizedString
- xsd:token
- xsd:language
- xsd:anyURI
- xsd:Name
- xsd:NCName
- xsd:QName
- xsd:ID
- xsd:IDREF
- xsd:IDREFS
- xsd:NMTOKEN
- xsd:NMTOKENS
- xsd:base64Binary
- xsd:hexBinary
- XForms associative array : every default type definition for XForms types
- xforms:string
- xforms:boolean
- xforms:decimal
- xforms:float
- xforms:double
- xforms:dateTime
- xforms:date
- xforms:time
- xforms:duration
- xforms:dayTimeDuration
- xforms:yearMonthDuration
- xforms:gDay
- xforms:gMonth
- xforms:gMonthDay
- xforms:gYear
- xforms:gYearMonth
- xforms:integer
- xforms:nonPositiveInteger
- xforms:nonNegativeInteger
- xforms:negativeInteger
- xforms:positiveInteger
- xforms:byte
- xforms:short
- xforms:int
- xforms:long
- xforms:unsignedByte
- xforms:unsignedShort
- xforms:unsignedInt
- xforms:unsignedLong
- xforms:normalizedString
- xforms:token
- xforms:language
- xforms:anyURI
- xforms:Name
- xforms:NCName
- xforms:QName
- xforms:ID"
- xforms:IDREF
- xforms:IDREFS
- xforms:NMTOKEN
- xforms:NMTOKENS
- xforms:base64Binary
- xforms:hexBinary
- xforms:email
- xforms:card-number
- xforms:url
- xforms:amount
- XSLTForms associative array : every default type definition for XSLTForms types
- xsltforms:decimal
- xsltforms:float
- xsltforms:double
- xsltforms:integer
- xsltforms:nonPositiveInteger
- xsltforms:nonNegativeInteger
- xsltforms:negativeInteger
- xsltforms:positiveInteger
- xsltforms:byte
- xsltforms:short
- xsltforms:int
- xsltforms:long
- xsltforms:unsignedByte
- xsltforms:unsignedShort
- xsltforms:unsignedInt
- xsltforms:unsignedLong
XForms Events Management
edit"Listener" class
editListener Class
- constructor function : creates a Listener object to an observer element and attaches a standard callback function
- attach method : attaches the event according to the current phase
- detach method : detaches the event according to the current phase
- clone method : creates a new listener for the given element
"XMLEvents" class
editXForms Event Management Class
- REGISTRY associative array : stores properties for each event
- bubbles : boolean
- cancelable : boolean
- defaultAction : handler function with empty function as default
- define function : convenient function to add a new event in the event registry
- dispatchList function : dispatches the same event at every target in a given list
- dispatch function : dispatches the given event at a given target with possibly different properties
- default event management :
- xforms-model-construct : fired at the end of the xforms.init() function before xforms-ready been fired
- bubbles : yes
- cancelable : no
- default handler : construct() method
- xforms-model-construct-done : fired at the end of the XFModel.construct() method after xforms-rebuild being fired
- bubbles : yes
- cancelable : no
- default handler : empty
- xforms-ready' : fired at the end of the xforms.init() function after xforms-model-construct been fired
- bubbles : yes
- cancelable : no
- default handler : empty
- xforms-model-destruct : fired in the xforms.close() function to every models
- bubbles : yes
- cancelable : no
- default handler : empty
- xforms-rebuild : fired in the xforms.closeChanges() function when a rebuild is required,
- xforms-model-construct : fired at the end of the xforms.init() function before xforms-ready been fired
in the XFModel.construct() method before xforms-model-construct-done being fired and in the XFSubmission.submit() method when the corresponding instance has just been replaced
- bubbles : yes
- cancelable : yes
- default handler : rebuild() method
- xforms-recalculate : fired in the xforms.closeChanges() function when a rebuild is not required,
at the end of the XFModel.rebuild() method and in the XFControl.valueChanged() method when the new value is different
- bubbles : yes
- cancelable : yes
- default handler : recalculate() method
- xforms-revalidate : fired at the end of the XFModel.recalculate() method
- bubbles : yes
- cancelable : yes
- default handler : revalidate() method
- xforms-reset : fired by a listener generated by the XSL transformation for the xforms:reset element
- bubbles : yes
- cancelable : yes
- default handler : reset() method
- xforms-submit : fired by a listener generated by the XSL transformation for the xforms:submit element
- bubbles : yes
- cancelable : yes
- default handler : submit() method
- xforms-refresh : fired at the end of the XFModel.revalidate() method
- bubbles : yes
- cancelable : yes
- default handler : refresh() method
- xforms-focus : fired by a listener generated by the XSL transformation for the xforms:setfocus action
- bubbles : yes
- cancelable : yes
- default handler : focus() method
- DOMActivate : fired by the XFTrigger.click() method and by a listener generated by the XSL transformation for the xforms:submit element
- bubbles : yes
- cancelable : yes
- default handler : empty
- DOMFocusIn : fired by the XFControl.focus() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- DOMFocusOut : fired by the xforms.blur() function to the element already having focus
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-select : fired by the XFToggle.toggle(), XFSelect.normalChange() functions and XFSelect.itemClick() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-deselect : fired by the XFToggle.toggle(), XFSelect.normalChange() functions and XFSelect.itemClick() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-value-changed : fired by the XFControl.refresh() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-insert : fired by the XFInsert.run() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-delete : fired by the XFDelete.run() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-valid : fired by XFControl.refresh() method via the XFControl.changeProp() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-invalid : fired by XFControl.refresh() method via the XFControl.changeProp() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-enabled : fired by XFControl.refresh() method via the XFControl.changeProp() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-disabled : fired by XFControl.refresh() method via the XFControl.changeProp() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-optional : fired by XFControl.refresh() method via the XFControl.changeProp() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-required : fired by XFControl.refresh() method via the XFControl.changeProp() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-readonly : fired by XFControl.refresh() method via the XFControl.changeProp() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-readwrite : fired by XFControl.refresh() method via the XFControl.changeProp() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-in-range : fired by the XFSelect.setValue() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-out-of-range : fired by the XFSelect.setValue() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-submit-done : fired by the XFSubmission.submit() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-submit-error : fired by the XFSubmission.submit() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-compute-exception : unused
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-binding-exception : fired by the XFBind.refresh() method
- bubbles : yes
- cancelable : yes
- default handler : empty
- xforms-dialog-open : fired by a listener generated by the XSL transformation for the xforms:show action
- bubbles : yes
- cancelable : yes
- default handler : show() method of the corresponding dialog
- xforms-dialog-close : fired by a listener generated by the XSL transformation for the xforms:hide action
- bubbles : yes
- cancelable : yes
- default handler : hide() method of the corresponding dialog
XPath Expressions Management
editXPath expressions are "compiled" (converted to Javascript objects creation instructions) by the XSLT transformation. There is an "XPath" object for each distinct (according to its text source) expression. An implicit cast is usually performed for each parameter.
XPathAxis Class
editXML Constants Class for axes as an associative array
NodeType Class
editXML Constants Class for node types as an associative array
XNode Class
editXNode Class
- constructor function : initializes specific properties
- getElementsByTagName method : gets an array of all elements with a given tag name for this XNode object
- getTextContent method : gets the text context for this XNode object
- appendChild method : appends a new child at this XNode object
- replaceChild method : replaces a child of this XNode object
- insertBefore method : inserts a child before another one of this XNode object
- removeChild method : removes a child of this XNode object
- setAttributeNS method : sets an attribute of this XNode object after creating it if necessary. "xsd:type" is interpreted to associate the corresponding type to this XNode object.
- getAttributeNS method : gets the value of an attribute of this XNode object
- removeAttributeNS method : removes an attribute of this XNode object
- cloneNode method : clones this XNode object
- init function : sets properties of this XNode object
- recycle function : clears every properties of this XNode object and of its child XNode objects
- create function : reuses a previously recycled XNode object or creates a new XNode object
XDocument Class
editXDocument Class based on XNode Class
- constructor function : creates a document XNode object
- clear method : recycles every XNode objects composing this XDocument object
- appendChild method : appends a node to this XDocument object
- createElementNS method : creates an element XNode object for this XDocument object
- createTextNode method : creates a text XNode object for this XDocument object
- createAttributeNS method : creates an attribute XNode object for this XDocument object
- getElementsByTagName method : gets an array of all elements with a given tag name for this XDocument object
- transformToText method : applies a text XSL transformation to this XDocument object
- unescape function : unescape entities within a serialized XML
- parse function : parses a serialized XML to load it into this XDocument object
- load function : gets a serialized XML at the given location to load it into this XDocument object
Writer Class
editWriter Class
- toString method : serializes an XNode object
XMLWriter Class
editXMLWriter Class
- toString method : serializes an XNode object
ArrayExpr Class
editXPath Expression Class for array expressions
- constructor function : initializes exprs property
- evaluate method : evaluates as a node set this expression object
BinaryExpr Class
editXPath Expression Class for binary expressions
- constructor function : initializes specific properties
- evaluate method : evaluates this Binary expression object. No precedence treatment required, this being already done at XSLT transformation step.
ExprContext Class
editContext for XPath Expression evaluation Class
- constructor function : initializes specific properties
- clone method : creates a new expression context based on this Expression Context object
- setNode method : set node and position properties for this Expression Context object
- initDeps method : initializes dependency collections for this Expression Context object
- addDepNode method : adds a node to the corresponding dependency collection for this Expression Context object
- addDepElement method : adds an element to the corresponding dependency collection for this Expression Context object
TokenExpr Class
editXPath Expression Class for token expressions
- constructor function : initializes the value property
- evaluate method : evaluates this Binary expression object value as a string value.
UnaryMinusExpr Class
editXPath Expression Class for unary minus expressions
- constructor function : initializes the expr property
- evaluate method : evaluates this Unary Minus expression object.
CteExpr Class
editXPath Expression Class for constant expressions
- constructor function : initializes the value property
- evaluate method : gets this Constant expression object value as is.
FilterExpr Class
editXPath Expression Class for filtering nodes according to a predicate
- constructor function : initializes specific properties
- evaluate method : evaluates this filtering expression object
FunctionCallExpr Class
editXPath Expression Class for core function calling
- constructor function : checks a core function has the given name, initializes specific properties, pushes arguments
- evaluate method : evaluates this function call expression object calling the corresponding Javascript function with the context and the same arguments
LocationExpr Class
editXPath Expression Class for location expressions
- constructor function : initializes absolute property and stacks successive steps
- evaluate method : recursively evaluates the successive steps of this location expression object
NodeTestAny Class
editXPath Expression Class for any node Expression ("*")
- constructor function : initializes absolute property and stacks successive steps
- evaluate method : always true
NodeTestName Class
editXPath Expression Class for node test expressions
- constructor function : initializes prefix and name properties
- evaluate method : evaluates as a boolean value if a given node has the same namespace and name as this expression object. Wildcard is supported as a valid namespace test as an extension.
NodeTestPI Class
editXPath Expression Class for processing instruction test expressions
- constructor function : initializes target property
- evaluate method : evaluates as a boolean value if a given node is a processing instruction with the same name as this expression object
NodeTestType Class
editXPath Expression Class for node type test expressions
- constructor function : initializes type property
- evaluate method : evaluates as a boolean value if a given node has the same type as this expression object
NSResolver Class
editXPath Expression Class for namespace resolving
- constructor function : initializes map property as an empty associative array
- registerAll method : registers all the namespaces from a given resolver in this Namespace Resolver object
- register method : registers a prefix and an uri in this Namespace Resolver object
- registerNotFound method : registers a prefix for a not found uri in this Namespace Resolver object
- lookupNamespaceURI method : looks up for the corresponding uri for a given prefix in this Namespace Resolver object
PathExpr Class
editXPath Expression Class for path expressions composed of a filter and a relative path
- constructor function : initializes the filter and rel properties
- evaluate method : first evaluates the filter then evaluates each combination with the relative path for this expression object
PredicateExpr Class
editXPath Expression Class for predicate expressions
- constructor function : initializes expr property
- evaluate method : evaluates as a boolean value this predicate expression object comparing a number value to current position if possible
StepExpr Class
editXPath Expression Class for location step expressions
- constructor function : initializes axis, nondetest and unlimited number of predicates properties
- evaluate method : evaluates as a node list this expression object according to the context
UnionExpr Class
editXPath Expression Class for binary union expressions
- constructor function : initializes expr1 and expr2 properties
- evaluate method : evaluates as a node set this expression object
Miscellaneous Functions
edit- stringValue function : string cast
- booleanValue function : boolean cast
- numberValue function : number cast
- booleanValue function : number cast
- xmlValue function : get the text value for the given node according to its type
- xmlResolveEntities function : resolves every HTML entities in a given string into corresponding characters
- stringSplit function : splits a string according to a character
XPath Class
editXPath Class
- constructor function : initializes properties and creates an associated namespace resolver. A compiled argument as string is interpreted as an error detected by the XSLT transformation.
- evaluate method : evaluates the complete XPath expression et catches occurring exceptions
- expressions associative array : stores every XPath object
- get method : get an XPath object according to a given source text
- new method : creates an XPath object if it doesn't already exists
- registerNS method : register a namespace for all XPath expressions
XPathFunction Class
editXPath Function Class
- constructor function : initializes properties
- acceptContext : whether the current context is required as first argument for this XPath Function object
- defaultTo : default argument
- DEFAULT_NONE : no default argument
- DEFAULT_NODE : current node
- DEFAULT_NODESET : array containing the current node
- DEFAULT_STRING : text value of the current node
- returnNodes : unused
- body : corresponding Javascript function
- call method : calls the corresponding Javascript function after managing default argument and context presence
XPathCoreFunctions Associative Array
editCore XPath Functions
- last()
- position()
- context()
- count(nodeset)
- id(node?)
- local-name(nodeset?)
- namespace-uri(nodeset?)
- name(nodeset?)
- string(nodeset?)
- concat(string, string, string*)
- starts-with(string, string)
- contains(string, string)
- substring-before(string, string)
- substring-after(string, string)
- substring(string, number) and substring(string?, number?, number?)
- compare(string, string)
- string-length(string?)
- normalize-space(string?)
- translate(string, string, string)
- boolean(object)
- not(boolean)
- true()
- false()
- lang(string)
- number(object)
- sum(nodeset)
- floor(number)
- ceiling(number)
- round(number)
- power(number, number)
- random()
- boolean-from-string(string)
- if(boolean, object, object)
- choose(boolean, object, object)
- avg(nodeset)
- min(nodeset)
- max(nodeset)
- count-non-empty(nodeset)
- index(string)
- nodeindex(string)
- property(string)
- instance(string?)
- now()
- local-date()
- local-dateTime()
- days-from-date(string)
- days-to-date(number)
- seconds-from-dateTime(string)
- seconds-to-dateTime(number)
- current()
- is-valid(nodeset?)
- is-card-number(nodeset?)
- digest(string, string, string?)
- upper-case(nodeset?)
- lower-case(nodeset?)
- transform(nodeset?, string)
- serialize(nodeset?)
Miscellaneous Functions
edit- stringValue function : string cast
- booleanValue function : boolean cast
- numberValue function : number cast
- booleanValue function : number cast
- xmlValue function : get the text value for the given node according to its type
- xmlResolveEntities function : resolves every HTML entities in a given string into corresponding characters
- stringSplit function : splits a string according to a character
Contributing
This page provides information for people interested in helping complete and maintain this wikibook. It describes the book's house style, sketches the current road map for improvements to the book, and provides a list of tasks that appear to need doing.
Like XSLTForms itself, this wikibook has a relatively small user community but a long life. The small community means that it may take a while for flaws and gaps in the book to be attended to; its longevity, however, suggests that the book is serving a useful function for some people. This page is an attempt to make it easier for work on the book to be coordinated and effective.
House style
editDon't overcrowd pages. Make distinct topics into distinct pages (bearing in mind that pages and sections grow more often than they shrink: collaborators in a wiki are more willing to add new material than to delete material contributed by others).
Provide concrete examples. Use the syntaxhighlight
element to tag them. And provide explanations and commentary to make clear what point the example is exhibiting.
Use the namespace prefixes listed in the section on Naming Conventions; if you need any namespace more than three times, it may be worth adding an entry there. Explicit namespace declarations are always OK, as long as the example remains legible.
If you leave a gap in a discussion (because you don't have time to work things out in full, or because you know a topic needs to be covered but you don't know enough to do it yourself), a comment in square brackets saying "[Fuller discussion of XYZ needed here.]" is a reasonable way to signal to readers that the coverage is incomplete and to other contributors that a gap needs filling at that point.
For consistency, it is a good idea if articles on functions and elements have roughly similar structures, with subheads for
- Description
- Syntax / Signature
- Examples and uses
- Known problems and issues
- Further information (places to go for more details)
(A template would probably be helpful.)
When you make new pages, remember to ensure that {{BookCat}} appears at the bottom of the page.
[More details needed here.]
Road map
editIn the immediate future, the main task for those working on this book is to fill in the obvious gaps.
- Pages which are mentioned on (linked from) the table of contents but which do not currently exist should be created, with appropriate content.
- Topics mentioned in the table of contents that are not currently linked to a page should be described on pages of their own.
- Gaps in the prose identified by bracketed comments should be filled (and the comments removed).
- New pages should be created for topics which ought to be covered but aren't. At a first approximation: any problem that has puzzled a new(ish) user of XSLTForms for more than an hour or so should (ideally) be addressed somewhere in the Getting_Started section (perhaps under Some Common Problems). Some obvious gaps in current coverage include:
- How to debug XForms; techniques for developing complex forms
- Using multiple instances
- Manage user-interface configuration (add a 'ui' instance)
- Basics of datatypes
- Interacting with the file system in XSLTForms; using the Java applet to read and save files
- And any problem that has occupied an experienced user of XSLTForms for more than half a day or a day should (ideally) be addressed in the Further Topics or Status sections. Obvious candidates include:
- Subforms in XSLTForms
- Making file-upload work in XSLTForms; making multipart form submission work
- Basic create/retrieve/update/delete (CRUD) operations in XSLTForms
- Working with events in XSLTForms
In the longer-term future it may be desirable to restructure the book a bit for clarity, and to extend its coverage. See the Talk page for the book's table of contents for proposals.
Some things that need doing
editIf you don't have the time or skills to undertake any of the tasks below, but you see something that needs doing, you can help by adding it to this list!
- The contents of the page on XSLTForms-only extensions should be spun off into multiple pages, one for each extension; the page itself should be essentially a detailed table of contents listing the extensions and hyperlinking to their descriptions.
- The XSLT transformation
xsltforms.xsl
should be commented using a tool like XSLTdoc, and the documentation should be supplied in the page liked from the Information for Contributors section of the table of contents.
- The Javascript documentation should probably be regenerated (only in consultation with Alain Couthures).
- The list of XSLTForms extensions should be made more systematic and complete; this may require systematically reading the back archives of the support list.
- It would be very helpful if there could be working forms on this site. Anyone with the knowledge and tenacity to wade through the technical and policy information about wikibooks would do a great service by finding out whether it's possible and how to do it, if it is possible, and recording the answers here.