SourceWritingTransformer
The Source Writing Transformer is very similar to the Cocoon version. It provides a means
to divert XML from the pipeline into an external file. It can also add or delete fragments
within the file. There are three tags that form the SourceWritingTransformer framework:
Source Writing Namespace
The SourceWritingTransformer tags exist in their own
namespace, which is the same as the Cocoon transformer: "http://apache.org/cocoon/source/1.0".
Source Writing Output
The transformer replaces the tags within the document with the results of the operation.
The generalised output (identical to Cocoon) is:
<source:sourceResult>
<source:action>new|overwritten|none</source:action>
<source:behaviour>write|insert<source:behaviour>
<source:execution>success|failure</source:execution>
<source:serializer>xml</source:serializer>
<source:source>Full file name of processed file</source:source>
<source:message>a message about what happened</source:message>
</source:sourceResult>
Source Write
Source write tags allow the writing of a complete file to a folder. The overall structure
is:
<source:write [create="true"]">
<source:source/>
[<source:path/>]
<source:fragment/>
</source:write>
where
- <create> attribute — defines whether to
create the file first if it does not exist.
- <source:source> — is the file name of the
file to be written. It can have pseudo variables such as "context://".
- <source:path> — is an optional XPath for
defining the root structure of the file with which the fragment is placed.
- <source:fragment> — is the fragment of XML
that will be written.
Note that there is no serializer
attribute that is present in Cocoon. For example the following structure:
<source:write create="true">
<source:source>context://test.xml</source:source>
<source:path>/root/AAA</source:path>
<source:fragment>
<BBB>
<CCC name="bob"/>
</BBB>
</source:fragment>
</source:write>
will write the following file (I have added indentation for clarity)
context://test.xml
<?xml version="1.0"?>
<root>
<AAA>
<BBB>
<CCC name="bob"/>
</BBB>
</AAA>
</root>
Note
If you omit <source:path> it is important that
the XML within <source:fragment> has only a single node, which
will become the root node of the written document.
If you do not as in this example:
<source:write create="true">
<source:source>context://configs/test.xml</source:source>
<source:path/>
<source:fragment>
<BBB/>
<CCC name="bob"/>
</source:fragment>
</source:write>
then the following error is returned
<source:sourceResult>
<source:action>new</source:action>
<source:behaviour>write<source:behaviour>
<source:execution>failure</source:execution>
<source:serializer>xml</source:serializer>
<source:source>/....../configs/test.xml</source:source>
<source:message>Problem processing source document in write-source:
Fragment must have one root element if no path declared</source:message>
</source:sourceResult>
Source Insert
Source insert tags allow the replacement/insertion of tags within a file. The overall structure
is:
<source:insert [create="true"]">
<source:source/>
<source:path/>
<source:fragment/>
[<source:replace/>]
</source:insert>
where
- <create> attribute — defines whether to
create the file first if it does not exist.
- <source:source> — is the file name of the
file to be written. It can have pseudo variables such as "context://".
- <source:path> — is an optional XPath for
defining the root structure of the file with which the fragment is placed.
- <source:fragment> — is the fragment of XML
that will be written.
- <source:replace> — an optional XPath to
select the node that is to be replaced by the XML fragment.
Note
Note that there is no @serializer attribute that is present in Cocoon.
Note also that the Cocoon <source:reinsert> tag is not used
— I confess that I did not understand exactly what was required here and so it
seemed to be safe to leave it out.
Assume that we have a file that has been created above:
context://test.xml
<?xml version="1.0"?>
<root>
<AAA>
<BBB>
<CCC name="bob"/>
</BBB>
</AAA>
</root>
The <source:insert> comes in several flavours:
Case 1 (replace not specified)
<source:insert create="true">
<source:source>context://configs/test.xml</source:source>
<source:path>/root/AAA</source:path>
<source:fragment>
<BBB/>
<CCC name="alice"/>
</BBB>
</source:fragment>
</source:insert>
will append the fragment as a child of /root/AAA:
context://test.xml
<?xml version="1.0"?>
<root>
<AAA>
<BBB>
<CCC name="bob"/>
</BBB>
<BBB>
<CCC name="alice"/>
</BBB>
</AAA>
</root>
Case 2 (replace specified, node exists, overwrite true)
<source:insert overwrite="true">
<source:source>context://configs/test.xml</source:source>
<source:path>/root/AAA</source:path>
<source:replace>BBB/CCC[ @name='alice' ]/parent::*</source:replace>
<source:fragment>
<BBB>
<CCC name="carol"/>
</BBB>
</source:fragment>
</source:insert>
will replace the second <BBB> node with the fragment:
context://test.xml
<?xml version="1.0"?>
<root>
<AAA>
<BBB>
<CCC name="bob"/>
</BBB>
<BBB>
<CCC name="carol"/>
</BBB>
</AAA>
</root>
Case 3 (replace specified, overwrite false)
<source:insert overwrite="false">
<source:source>context://configs/test.xml</source:source>
<source:path>/root/AAA</source:path>
<source:replace>BBB/CCC[ @name='alice' ]/parent::*</source:replace>
<source:fragment>
<BBB>
<CCC name="carol"/>
</BBB>
</source:fragment>
</source:insert>
causes no action to be taken.
Case 4 (replace specified, node does not exist, overwrite true or
false)
<source:insert>
<source:source>context://configs/test.xml</source:source>
<source:path>/root/AAA</source:path>
<source:replace>BBB/CCC[ @name='oscar' ]/parent::*</source:replace>
<source:fragment>
<BBB>
<CCC name="carol"/>
</BBB>
</source:fragment>
</source:insert>
will replace the second <BBB> node with the fragment:
context://test.xml
<?xml version="1.0"?>
<root>
<AAA>
<BBB>
<CCC name="bob"/>
</BBB>
<BBB>
<CCC name="alice"/>
</BBB>
<BBB>
<CCC name="carol"/>
</BBB>
</AAA>
</root>
Source Delete
Source delete tags delete the specified source file. The overall structure is:
<source:delete>
<source:source/>
</source:delete>
where
- <source:source> — is the file name of the
file to be deleted. It can have pseudo variables such as "context://".
For example:
<source:delete>
<source:source>context://configs/test.xml</source:source>
</source:delete>
Copyright 2006 – 2023 Hugh Field-Richards. All Rights
Reserved.