Subject: Re: Finding first difference between 2 text strings
From: "James A. Robinson" <jim.robinson@xxxxxxxxxxxx>
Date: Thu, 10 Sep 2009 09:03:14 -0700
|
> Comparing strings can also be time consuming for long strings, so I'd
> like an "inexpensive" solution, if there is one.
>
> Any suggestions for finding the first difference in 2 strings (besides a
> linear march through the strings in my XSL transformation)?
Honestly, a march through the strings as you indicate above is what first
came to my mind. I'd be curious to see what other solutions are presented!
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="sample.namespace"
exclude-result-prefixes="xs f"
version="2.0">
<xsl:output method="text" />
<xsl:variable name="a" as="xs:string" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="b" as="xs:string" select="'abcdefghijklmnopqrstuvwxy0'" />
<xsl:template match="/">
<xsl:sequence select="f:mismatch($a, $b)" />
</xsl:template>
<xsl:function name="f:mismatch" as="xs:integer?">
<xsl:param name="a" as="xs:string" />
<xsl:param name="b" as="xs:string" />
<xsl:sequence
select="for $r in f:mismatch-position(
string-to-codepoints($a), string-to-codepoints($b), 1)
return if ($r eq 0) then () else $r" />
</xsl:function>
<xsl:function name="f:mismatch-position" as="xs:integer">
<xsl:param name="a" as="xs:integer*" />
<xsl:param name="b" as="xs:integer*" />
<xsl:param name="pos" as="xs:integer" />
<xsl:sequence select="
if (empty($a) and empty($b))
then 0
else if ($a[1] ne $b[1])
then $pos
else
f:mismatch-position(remove($a, 1), remove($b, 1), $pos + 1)" />
</xsl:function>
</xsl:stylesheet>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
James A. Robinson jim.robinson@xxxxxxxxxxxx
Stanford University HighWire Press http://highwire.stanford.edu/
+1 650 7237294 (Work) +1 650 7259335 (Fax)
|