Subject: Re: String comparison
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Fri, 24 Sep 2010 06:45:29 -0700
|
On Fri, Sep 24, 2010 at 2:41 AM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
>
>> Input
>> ====
>> <pages><first-page>10635<first-page><last-page>10637<last-page></pages>
>>
>> Output
>> =====
>> <pages><first-page>10635<first-page>-<last-page>7<last-page></pages>
>>
>>
>
> I played with this for a bit and couldn't come up with anything
significantly better than your code, other that putting it in a loop or
recursion to generalize it over any length of number. You don't say whether
you want a 2.0 or 1.0 solution, but I couldn't see anything obvious in 2.0
that would make it significantly easier.
Here is a good functional solution using the str-zipWith()
function/template of FXSL:
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:myComp="f:myComp"
exclude-result-prefixes="f myComp"
>
<xsl:import href="str-zipWith.xsl"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<!-- To be applied on: any -->
<myComp:myComp/>
<xsl:template match="/">
<xsl:variable name="vFun" select="document('')/*/myComp:*[1]"/>
<xsl:variable name="vStr1" select="'123456'"/>
<xsl:variable name="vStr2" select="'1234X56'"/>
<xsl:variable name="vDiffs">
<xsl:call-template name="str-zipWith">
<xsl:with-param name="pFun" select="$vFun"/>
<xsl:with-param name="pStr1" select="$vStr1"/>
<xsl:with-param name="pStr2" select="$vStr2"/>
</xsl:call-template>
</xsl:variable>
$vStr1 = "<xsl:value-of select="$vStr1"/>"
$vStr2 = "<xsl:value-of select="$vStr2"/>"
diff($vStr1, $vStr2) = "<xsl:text/>
<xsl:value-of select="
substring($vStr2,
string-length(substring-before($vDiffs, '*'))+1)"/>"
</xsl:template>
<xsl:template match="myComp:*" mode="f:FXSL">
<xsl:param name="arg1"/>
<xsl:param name="arg2"/>
<xsl:value-of select="substring('* ', ($arg1 = $arg2) +1)"/>
</xsl:template>
</xsl:stylesheet>
when applied on any XML document (not used), produces the wanted,
correct result:
$vStr1 = "123456"
$vStr2 = "1234X56"
diff($vStr1, $vStr2) = "X56"
I first provided the str-zipWith template to this list eight years ago
with this answer ("A Functional Solution for "binary or" -- the
str-zipWith template") that showed how to implement bit-wise
arithmetic:
http://sources.redhat.com/ml/xsl-list/2002-09/msg01034.html
Here is its version I used today:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f" >
<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" mode="f:FXSL">
<xsl:with-param name="arg1" select="substring($pStr1, 1, 1)"/>
<xsl:with-param name="arg2" 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>
--
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
Never fight an inanimate object
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play
-------------------------------------
I enjoy the massacre of ads. This sentence will slaughter ads without
a messy bloodbath.
| Current Thread |
Michael Kay - 24 Sep 2010 09:41:41 -0000
- pankaj . c - 24 Sep 2010 10:08:15 -0000
- Dimitre Novatchev - 24 Sep 2010 13:46:02 -0000 <=
|
|