[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] String comparison


Subject: Re: [xsl] 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
Keywords
xml