<abstract>This document describes the Source Writing transformer of Cocoon.</abstract>
</header>
<body>
<s1 title="Source Writing Transformer">
<p>Diverts xml from a pipeline, writing it to a Source (or
deleting it).</p>
<p>Thankfully, <code>FileSource</code> is no longer the only <code>Source</code> that currently implements <code>WritableSource</code>; there are implementations of WebDAV and Apache Slide WritableSources in the scratchpad. Hopefully further <code>ModifiableSource</code> implementations (XMLDB, CVS, Email, SQL, etc.) will be appear in the future.</p>
<p>The source:write tag can take optional attributes, <code>create</code> (defaults to 'true') and <code>serializer</code> (defaults to the serializer set up in the definition or invocation of the transformer).</p>
<p>Replaces the entire content of a <code>Source</code> (specified by the <code><![CDATA[<source:source/>]]></code> tag) with the contents of the <code><![CDATA[<source:fragment/>]]></code> tag, if @create is 'true', a new asset will be created if one does not already exist.</p>
<p>The <code><![CDATA[<source:source/>]]></code> and <code><![CDATA[<source:fragment/>]]></code> tags are required, a <code><![CDATA[<source:path/>]]></code> tag is optional, if specified, the value is an used as an XPath to generate xml in your <code>Source</code>, inwhich to wrap your content.</p>
<s3 title="source:source">
<p>The System ID of the <code>Source</code> to be written to.</p>
<p>eg: <code><![CDATA[<source:source>docs/blah.xml</source:source>]]></code> or <code><![CDATA[<source:source>context:/blah.xml</source:source>]]></code> etc.</p>
</s3>
<s3 title="source:fragment">
<p>The XML Fragment to be written.</p>
<p>eg: </p>
<source>
<![CDATA[
<source:fragment><foo>
<bar id="dogcow"/>
</foo></source:fragment>
]]>
</source>
<p>or</p>
<source>
<![CDATA[
<source:fragment>
<foo/>
<bar>
<dogcow/>
<bar/>
</source:fragment>
]]>
</source>
<p>etc.</p>
<note>The second example type, can only be used when the <code><![CDATA[<source:path/>]]></code> tag has been specified.</note>
</s3>
<s3 title="source:path">
<p>[Optional] XPath to specify how your content is wrapped</p>
<p>eg: <code><![CDATA[<source:path>doc</source:path>]]></code> - your content is placed inside a <code><![CDATA[<doc/>]]></code> root tag.</p>
<note>If this parameter is omitted, your content MUST have only ONE top-level node.</note>
</s3>
</s2>
<s2 title="source:insert">
<p>The source:insert tag can take optional attributes, <code>create</code> (defaults to 'true') and <code>serializer</code> (defaults to the serializer set up in the definition or invocation of the transformer).</p>
<p>Inserts into a <code>Source</code> (specified by the <code><![CDATA[<source:source/>]]></code> tag) the contents of the tag <code><![CDATA[<source:fragment/>]]></code> at the XPath location specified in the <code><![CDATA[<source:path/>]]></code> tag, if @create is 'true', a new <code>Source</code> will be created if one does not already exist.</p>
<p>The <code><![CDATA[<source:source/>]]></code>, <code><![CDATA[<source:path/>]]></code> and <code><![CDATA[<source:fragment/>]]></code> tags are all required, the <code><![CDATA[<source:replace/>]]></code> and <code><![CDATA[<source:reinsert/>]]></code> tags are optional.</p>
<s3 title="source:source">
<p>The System ID of the <code>Source</code> to be inserted into.</p>
<p>eg: <code><![CDATA[<source:source>docs/blah.xml</source:source>]]></code> or <code><![CDATA[<source:source>context:/blah.xml</source:source>]]></code> etc.</p>
</s3>
<s3 title="source:fragment">
<p>The XML Fragment to be written.</p>
<p>eg:</p>
<source>
<![CDATA[
<source:fragment>
<foo>
<bar id="dogcow"/>
</foo>
</source:fragment>
]]>
</source>
<p>or</p>
<source>
<![CDATA[
<source:fragment>
<foo/>
<bar>
<dogcow/>
<bar/>
</source:fragment>
]]>
</source>
<p>etc.</p>
</s3>
<s3 title="source:path">
<p></p>
</s3>
<s3 title="source:replace">
<p>[Optional] XPath (from <code><![CDATA[<source:path/>]]></code>) to select the node that is replaced by your new content</p>
<p>eg: <code><![CDATA[<source:replace>foo/bar/dogcow/@status='cut'</source:replace>]]></code> (is equivalent to this in XSLT: <code>select="foo[bar/dogcow/@status='cut']"</code>), what gets replaced is the <code><![CDATA[<foo/>]]></code> which has a <code><![CDATA[<bar/>]]></code> with a <code><![CDATA[<dogcow status="cut"/>]]></code> in it.</p>
<p>The <code>overwrite</code> attribute of the parent <code><![CDATA[<source:insert/>]]></code> is used to check if replacing is allowed. If <code>overwrite</code> is 'true' (the default) the node is replaced. If <code>overwrite</code> is 'false' the node is only inserted if the replace node is found.</p>
</s3>
<s3 title="source:reinsert">
<p>[Optional] The XPath (relative to <code><![CDATA[<source:replace/>]]></code>) to backup the contents of the overwritten node to.</p>
<p>eg: <code><![CDATA[<source:reinsert>foo/versions</source:reinsert>]]></code> or <code><![CDATA[<source:reinsert>/doc/versions/foo</source:reinsert>]]></code>.</p>
<p>If specified and a node is replaced, all children of this replaced node will be reinserted at the given path.</p>
</s3>
</s2>
<s2 title="Notes">
<ul>
<li>if 'replace' is not specified, your 'fragment' is appended as a child of 'path'.</li>
<li>if 'replace' is specified and it exists and 'overwrite' is true, your 'fragment' is inserted in 'path', before 'replace' and then 'replace' is deleted.</li>
<li>if 'replace' is specified and it exists and 'overwrite' is false, no action occurs.</li>
<li>if 'replace' is specified and it does not exist and 'overwrite' is true, your 'fragment' is appended as a child of 'path'.</li>
<li>if 'replace' is specified and it does not exist and 'overwrite' is false, your 'fragment' is appended as a child of 'path'.</li>
<li>if 'reinsert' is specified and it does not exist, no action occurs.</li>
</ul>
</s2>
<s2 title="source:delete">
<p>This instruction takes only a <code><![CDATA[<source:source/>]]></code>
parameter (as a child tag) and deletes the corresponding
source. All other <code>source:*</code> tags are ignored, if
present: this allows for easy source-write instructions to be
generated on the fly (e.g. by a stylesheet). Just change
<code>source:write</code> to <code>source:delete</code> and
<p>This is the kind of information that the <code>SourceWritingTransformer</code> outputs to the pipeline, replacing the original <code>source:write</code> and <code>source:insert</code> tags</p>
<p>Namespace handling: namespace declarations are not copied to the <code>Source</code>, resulting in invalid XML.</p>
<p>I cannot get the 'insert before' example working, which uses the <code><![CDATA[<source:reinsert/>]]></code> tag.</p>
</s1>
<s1 title="Warning">
<p>It is not known how robust this transformer is under even moderate load, especially when it comes to more than one person modifying the same file at the same time.</p>