Intent
Some features need configuration files that may vary just a little for different situations. This pattern has beed designed to avoid redundancy (by rewriting almost same files) and complexity (by using XSLT) while resolving these different situations.
A XSLT implementation is provided.
Motivation
There are a lot of situations where configuration files only differ a little. To resolve this situation, we may write specific XSLT (or java, ...) code.
To avoid this complexity that decreases maintenance and usability, we may create a filter (like the Role-filter cocoon transformer) in XSLT, that will selects (delete or keeps) elements according the rule provided (and not only the user's role).
For example, if you have the following fragment that describes a form, you may have create and update modes in the same file :
Usage
It may be used when you have files that differ only a little. Two elements, in http://bluexml.org/filter/1.0 namespace, are available :
<?xml version="1.0"?>
<root xmlns:filter="">
<A>
<filter:keep-current-element when="onlya"/>
</A>
<B>
<filter:keep-current-element when="nota"/>
</B>
</root>It is useful when working with static files. If you dynamically generate your files, generate directly the file you need, I think you will avoid problems.
From a performance point of view, there is no impact because you will use it with configuration files that are usually well cached by the system.
Structure/Architecture
Component
- filter:tags : tags in filter namespace and processed by the filter
- condition : the condition to encounter to realize the action indicated
If you take the above example :
- if condition is 'onlya', then only element A will be kept.
- if condition is 'nota', then only element B will be kept.
Implementation
This is a very simple implementation that compares condition parameter with @when
<!--|
| CVS $Id: filter.xsl,v 1.4 2005/08/03 13:41:37 cvsjck Exp $
|
| This stylesheet filters elements and deletes or keeps them according they
| verify the condition or not.
|
| @author jck@bluexml.com
| @copyright 2004-2005 BlueXML SARL. All rights reserved.
|-->
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:filter="http://bluexml.org/filter/1.0">
<!--|
| Condition
| Usually user's role, view, ... To be satisfied, the condition parameter
| must contain (include) the string in @when attribute
| For example :
| * condition = role-dataadmin, when = dataadmin => verified
| * condition = user-anonymous, when = dataadmin => not verified
|-->
<xsl:param name="condition">sysadmin-create</xsl:param>
<xsl:param name="log">nodebug</xsl:param>
<!--|
| For each element, we 'reserve' the element and attribute creation
| We first check each available rule and apply it
| Finally we eventually copy the others attributes
| which is not correct.
|
| @param @when the condition to verify
| @returns the node if the condition is verified, nothing otherwise
|
| @TODO : the conditions admin-create and create are realized the same way.
| It may be considered like a bug :-)
|-->
<xsl:template match="*[filter:delete-current-node]">
<xsl:variable name="results">
<xsl:for-each select="filter:delete-current-node">
<xsl:if test="'debug' = $log">
When = <xsl:value-of select="@when"/>
</xsl:if>
<xsl:if test="contains($condition, @when)">1</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:if test="'debug' = $log">
Results = <xsl:value-of select="$results"/>
Condition = <xsl:value-of select="$condition"/>
Result = <xsl:value-of select="contains($condition, @when)"/>
</xsl:if>
<xsl:if test="not(contains($results, '1'))">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="*[filter:keep-current-node]">
<xsl:variable name="results">
<xsl:for-each select="filter:keep-current-node">
<xsl:if test="'debug' = $log">
When = <xsl:value-of select="@when"/>
</xsl:if>
<xsl:if test="contains($condition, @when)">1</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:if test="'debug' = $log">
Results = <xsl:value-of select="$results"/>
Condition = <xsl:value-of select="$condition"/>
Result = <xsl:value-of select="contains($condition, @when)"/>
</xsl:if>
<xsl:if test="contains($results, '1')">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
More information
This web page is available in html format on http://www.bluexml.org. You may have help on cocoon or bluexml mailing lists.