Background
I created a minimal webapp and found the following remark from Geoff Howard in #1 CreateMinimalWebapp - you have to read this reference 1 to understand the context of what we are going to do:
Geoff Howard wrote:
2. edit lib/jars.xml to comment out/remove all the optional jars except the ones noted above
1. could be done with an xsl transform
Goal
You will learn how to write a xsl transform that will remove certain XML-elements. This transform is capable of exceptions. I wrote that for cocoon 2.0.3. With 2.1.* the blocks are easy2exclude but still a good example for a transformation.
Introduction
There are 2 Steps to do. This steps are achieved by 2 XSLT- files.
- Step 1 Label lib which should be excluded with "2exclude", leave exceptions untouched.
Step 1a Label lib which should be excluded with "2exclude"
Step 1b Leave exceptions untouched
Step 2 Copy all elements except those which are labeled "2exclude"
sitemap.snippet:
<map:pipeline> <!-- Step 1: Label lib which should be excluded with "2exclude", leave exceptions untouched. --> <map:match pattern="2Xclude.xml"> <map:generate src="xml/jars.xml"/> <map:transform src="xsl/jars2exclude.xsl"/> <map:serialize type="xml"/> </map:match> <!-- Step 2: Copy all elements except those which are labeled "2exclude"--> <map:match pattern="exclude"> <map:generate src="cocoon:/2Xclude.xml"/> <map:transform src="xsl/exclude2jars.xsl"/> <map:serialize type="xml"/> </map:match> </map:pipeline>
Step 1a: Label lib which should be excluded with "2exclude"
The first xslt (jars2exclude.xsl #2) checks the <lib> element form the jars.xml whether it starts with 'optional/' (the dir to exclude files from). If so, they will be labeled "2exclude" (there are exceptions - you will see later).
The code looks like this: {{{<xsl:template match="lib"> <lib>
<xsl:choose>
<!--==Excluding dir ==-->
<xsl:when test="starts-with(text(), 'optional/')">
- 2exclude
</xsl:when>
<!--/==Excluding dir ==-->
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</lib> </xsl:template>}}}
The jars.xml looks like e.g.:
{{{... <file>
<title>The XML parser</title> <description>Xerces is an XML parser.</description> <used-by>Cocoon</used-by> <lib>core/xercesImpl-2.0.0.jar</lib> <homepage>http://xml.apache.org/xerces-j/</homepage>
</file> ...}}} The example file would not meet the criteria (starts-with(text(), 'optional/')). The following would: {{{<file>
<title>Servlet API</title> <description/> <used-by>Cocoon</used-by> <lib>optional/servlet_2_2.jar</lib> <homepage>http://jakarta.apache.org/tomcat/</homepage>
</file>}}} But this certain file has to be left untouched #1 - this is one of n exceptions (2 are mentioned in #1, but I need more<-n exception). This will now be explained.
Step 1b Leave exceptions untouched
We introduced one <xsl:choose>. If we nested a little bit deeper we can define exceptions. An exception looks like this: {{{<xsl:when test="substring-after(text(), 'optional/')='servlet_2_2.jar'">
<xsl:value-of select="."/>
</xsl:when>}}} You can define as many exceptions as you want: {{{<lib> <xsl:choose> <!--==Excluding dir ==-->
<xsl:when test="starts-with(text(), 'optional/')">
<xsl:choose>
<!--==without the exceptions (as many as you want just add a <xsl:when/>==-->
<xsl:when test="substring-after(text(), 'optional/')='fop-0.20.4.jar'">
<xsl:value-of select="."/>
</xsl:when> <xsl:when test="substring-after(text(), 'optional/')='servlet_2_2.jar'">
<xsl:value-of select="."/>
</xsl:when> <xsl:when test="substring-after(text(), 'optional/')='commons-jxpath-1.0.jar'">
<xsl:value-of select="."/>
</xsl:when>
<!--/==without the exceptions==-->
<xsl:otherwise>2exclude</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!--/==Excluding dir ==-->
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose> </lib>}}}
The result of the transformation #2 will look like this:
<file> <title>XML Catalog Entity Resolver</title> ... <lib>2exclude</lib> ... </file> <file> <title>Servlet API</title> ... <lib>optional/servlet_2_2.jar</lib> ... </file>
Step 2: Copy all elements except those which are labeled "2exclude"
Transforming this result with exclude2jars.xsl #3 will result in the new jar.xml (without the exclusions, but with the exceptions). We just have to introduce another XPath function
{{{<xsl:template match="jars"> <jars> <xsl:copy-of select="file[lib!='2exclude']"/> </jars> </xsl:template>}}}BR HTH
King regards
Thorsten Scherler
Reference
http://wiki.cocoondev.org/Wiki.jsp?page=CreateMinimalWebapp
jars2exclude.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="jars">
<jars>
<xsl:apply-templates select="file"/>
</jars>
</xsl:template>
<xsl:template match="file">
<file>
<xsl:apply-templates/>
</file>
</xsl:template>
<!--================Parsing of value===============================-->
<xsl:template match="title">
<title>
<xsl:value-of select="."/>
</title>
</xsl:template>
<xsl:template match="description">
<description>
<xsl:value-of select="."/>
</description>
</xsl:template>
<xsl:template match="used-by">
<used-by>
<xsl:value-of select="."/>
</used-by>
</xsl:template>
<!--==Excluding dir without the exceptions==-->
<xsl:template match="lib">
<lib>
<xsl:choose>
<!--==Excluding dir ==-->
<xsl:when test="starts-with(text(), 'optional/')">
<xsl:choose>
<!--==without the exceptions==-->
<xsl:when test="substring-after(text(), 'optional/')='fop-0.20.4.jar'">
<xsl:value-of select="."/>
</xsl:when>
<xsl:when test="substring-after(text(), 'optional/')='servlet_2_2.jar'">
<xsl:value-of select="."/>
</xsl:when>
<xsl:when test="substring-after(text(), 'optional/')='commons-jxpath-1.0.jar'">
<xsl:value-of select="."/>
</xsl:when>
<xsl:otherwise>2exclude</xsl:otherwise>
<!--/==without the exceptions==-->
</xsl:choose>
</xsl:when>
<!--/==Excluding dir ==-->
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</lib>
</xsl:template>
<xsl:template match="homepage">
<homepage>
<xsl:value-of select="."/>
</homepage>
</xsl:template>
</xsl:stylesheet>exclude2jars.xsl:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="jars"> <xsl:comment> Add an entry for each jar file used by Cocoon, following the other entries Author: Ovidiu Predescu "ovidiu@cup.hp.com" Date: May 23, 2002 jars2exclude have been used. Author: Thorsten Scherler "thorsten@apache.org" Date: March 06, 2003 This is the modified jars.xml. </xsl:comment> <jars> <xsl:copy-of select="file[lib!='2exclude']"/> </jars> </xsl:template> </xsl:stylesheet>
jars2exclude.xml {{{<?xml version="1.0" encoding="UTF-8"?> <!--
- Add an entry for each jar file which should be excluded by Cocoon!
Author: Thorsten Scherler "thorsten.scherler@wyona.org" Date: March 05, 2003
-->
<jars2exclude>
<exclude>
<dir2exclude>optional/</dir2exclude> <except>fop-0.20.4.jar</except> <except>commons-jxpath-1.0.jar</except> <except>servlet_2_2.jar</except>
</exclude>
</jars2exclude> }}} sitemap.snippet:
<map:pipeline> <!-- Step 1: Label lib which should be excluded with "2exclude", leave exceptions untouched. --> <map:match pattern="2Xclude.xml"> <map:generate src="xml/jars.xml"/> <map:transform src="xsl/jars2exclude.xsl"/> <map:serialize type="xml"/> </map:match> <!-- Step 2: Copy all elements except those which are labeled "2exclude"--> <map:match pattern="exclude"> <map:generate src="cocoon:/2Xclude.xml"/> <map:transform src="xsl/exclude2jars.xsl"/> <map:serialize type="xml"/> </map:match> </map:pipeline>