XSLTForms/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
[edit | edit source]The 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 | edit source]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
[edit | edit source]In 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
[edit | edit source]To 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.]