This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
The filter and str-filter functions (Was: Re: How to filter characters from a string?)
- From: Dimitre Novatchev <dnovatchev at yahoo dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Thu, 28 Mar 2002 13:24:04 -0800 (PST)
- Subject: [xsl] The filter and str-filter functions (Was: Re: How to filter characters from a string?)
- Reply-to: xsl-list at lists dot mulberrytech dot com
Greg Faron <gfaron at integretechpub dot com> wrote:
> I'm practicing XSLT and decided to write my own Base 64 encoder
> and decoder templates. The rules for Base 64 Encoding say that only
> the following characters (in an encoded file) should be examined upon
> decoding:
> <xsl:variable name="base64Map"
>select="'ABCDEFGHIJKLMNOPQRSTUVWXYZabcedfghijklmnopqrstuvwxyz01234567890+/='"/>
>
> This means that I would like to filter out every character that is
> not one of the 65 above characters. I realize that I could do this
> partially with translate(), but then I would need to specify every
> possible illegal character, of which there are thousands (if you have
> Unicode characters in there). A smaller version of such a command
> would be translate($encodedString,
> $base64Map,
> concat($base64Map,
> '=

> `~!@#$%^&*()-_)"'[]{}|\<>,.?;:'))
>
> Are there any templates or commands to delete any character from
> the first argument that DOESN'T appear in the second argument? I'm
> using Microsoft XSLT engine MSXSL4.
Hi Greg,
Here's a function from the next release of FXSL, which filters
characters from a string using a given predicate (condition) function.
This function is str-filter() and is the string analog of the filter()
function, which filters nodes from a node-set.
str-filter.xsl:
--------------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template name="str-filter">
<xsl:param name="pStr"/>
<xsl:param name="pController" select="/.."/>
<xsl:param name="pElName" select="'str'"/>
<xsl:element name="{$pElName}">
<xsl:call-template name="_str-filter">
<xsl:with-param name="pStr" select="$pStr"/>
<xsl:with-param name="pController" select="$pController"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<xsl:template name="_str-filter">
<xsl:param name="pStr" />
<xsl:param name="pController" select="/.."/>
<xsl:if test="not($pController)">
<xsl:message terminate="yes">
[str-filter]Error: pController not specified.
</xsl:message>
</xsl:if>
<xsl:if test="$pStr">
<xsl:variable name="vthisChar" select="substring($pStr, 1, 1)"/>
<xsl:variable name="vHolds">
<xsl:apply-templates select="$pController">
<xsl:with-param name="arg1" select="$vthisChar"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:if test="string($vHolds)">
<xsl:copy-of select="$vthisChar"/>
</xsl:if>
<xsl:call-template name="_str-filter">
<xsl:with-param name="pStr" select="substring($pStr, 2)"/>
<xsl:with-param name="pController" select="$pController"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
And here's a small test:
teststr-Filter.xsl:
------------------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myIsAlpha="f:myIsAlpha"
>
<xsl:import href="str-filter.xsl"/>
<!-- To be applied on any input xml file -->
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<myIsAlpha:myIsAlpha/>
<xsl:template match="/">
<xsl:variable name="vIsAlpha"
select="document('')/*/myIsAlpha:*[1]"/>
Filtering by IsAlpha:
filter('A1b3C67DE+', IsAlpha) =
<xsl:call-template name="str-filter">
<xsl:with-param name="pStr" select="'A1b3C67DE+'"/>
<xsl:with-param name="pController" select="$vIsAlpha"/>
</xsl:call-template>
</xsl:template>
<xsl:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="vLower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="vAlpha" select="concat($vUpper, $vLower)"/>
<xsl:template name="myIsAlpha" match="myIsAlpha:*">
<xsl:param name="arg1"/>
<xsl:if test="contains($vAlpha, $arg1)">1</xsl:if>
</xsl:template>
</xsl:stylesheet>
The result of applying this transformation is:
Filtering by IsAlpha:
filter('A1b3C67DE+', IsAlpha) =
<str>AbCDE</str>
Hope this helped.
Cheers,
Dimitre Novatchev.
__________________________________________________
Do You Yahoo!?
Yahoo! Movies - coverage of the 74th Academy Awards®
http://movies.yahoo.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list