Subject: [xsl] A Functional Solution for "binary or" -- the str-zipWith template From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Thu, 26 Sep 2002 00:37:07 -0700 (PDT) |
Rubén <rubenm at telepolis dot com> wrote: > Hello list! I couldn't find a "binary-or" (or "mask-or") operation in > XPath 1.1 so I tried to emulate it with a template. I wrote a > recursive implementation but I'm not very happy with the result. I > wonder if there is a simpler (and maybe more efficient) solution. > Any suggestions? Hi Rubén, For any instance of a class of problems, requiring to perform an operation on two lists memberwise, the functional solution is the zipWith() function, which is implemented in FXSL. A string is a special kind of list in XSLT, because we do not have a "char" datatype, and cannot represent a string as a list of chars. This is why every FXSL function, which operates on lists (implemented as node-sets) has also a string analogue. Here's the string analog of zipWith(): str-zipWith.xsl: --------------- <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:template name="str-zipWith"> <xsl:param name="pFun" select="/.."/> <xsl:param name="pStr1" select="/.."/> <xsl:param name="pStr2" select="/.."/> <xsl:if test="string-length($pStr1) and string-length($pStr2)"> <xsl:apply-templates select="$pFun"> <xsl:with-param name="pArg1" select="substring($pStr1, 1, 1)"/> <xsl:with-param name="pArg2" select="substring($pStr2, 1, 1)"/> </xsl:apply-templates> <xsl:call-template name="str-zipWith"> <xsl:with-param name="pFun" select="$pFun"/> <xsl:with-param name="pStr1" select="substring($pStr1, 2)"/> <xsl:with-param name="pStr2" select="substring($pStr2, 2)"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet> Now let's test it to solve your problem -- we need to "or" two strings containing only 0-s or 1-s: test-str-zipWith.xsl: -------------------- <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:myOr="f:myOr" > <xsl:import href="str-zipWith.xsl"/> <!-- to be applied on numList.xml --> <xsl:output method="text"/> <myOr:myOr/> <xsl:template match="/"> <xsl:variable name="vApos">'</xsl:variable> <xsl:variable name="vNL" select="'
'"/> <xsl:variable name="vFun" select="document('')/*/myOr:*[1]"/> <xsl:value-of select="concat(' ', $vApos, /*/*[1], $vApos, $vNL, 'or', $vNL, ' ', $vApos, /*/*[2], $vApos, $vNL, '=', $vNL, ' ', $vApos )"/> <xsl:call-template name="str-zipWith"> <xsl:with-param name="pFun" select="$vFun"/> <xsl:with-param name="pStr1" select="/*/*[1]"/> <xsl:with-param name="pStr2" select="/*/*[2]"/> </xsl:call-template> </xsl:template> <xsl:template match="myOr:*"> <xsl:param name="pArg1"/> <xsl:param name="pArg2"/> <xsl:value-of select="number(number($pArg1) or number($pArg2))"/> </xsl:template> </xsl:stylesheet> Let's apply the above transformation on the following source xml: test-str-zipWith.xml: -------------------- <test-str-zipWith> <str>001110101000</str> <str>101010101001</str> </test-str-zipWith> The result is: ------------- '001110101000' or '101010101001' = '101110101001 I can immediately implement "binary and", "xor", some kind of primitive encryption and ***any*** character-wise operation. The versions of zipWith for more than two lists (and their string analogues) are left as an exercise to the reader :o) Hope this helped. ===== Cheers, Dimitre Novatchev. http://fxsl.sourceforge.net/ -- the home of FXSL __________________________________________________ Do you Yahoo!? New DSL Internet Access from SBC & Yahoo! http://sbc.yahoo.com XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] PHP with XML/XSL in Webbr, Geoff | Thread | [xsl] input + xsl:attribute, Stevenson Ngila |
[xsl] PHP with XML/XSL in Webbrowse, Martin Gundersen | Date | RE: [xsl] PHP with XML/XSL in Webbr, James Fuller |
Month |