Parece que necesita un position-dependent checksum. ¿Estás pidiendo una implementación XSLT, o solo el algoritmo?
Aquí hay un implementation of Fletcher's checksum en C, que no debería ser muy difícil de portar a XSLT.
Actualización: A continuación se muestra una adaptación XSLT 2.0 de la suma de comprobación de Fletcher. Si es lo suficientemente rápido, depende del tamaño de sus datos y de la cantidad de tiempo que tenga. Me interesaría saber cómo van tus exámenes. Para optimizar, intentaría cambiar xs:integer
a xs:int
.
Tenga en cuenta que he sustituido la adición simple para el O bit a bit (|
) de la implementación a la que he vinculado anteriormente. No estoy realmente calificado para analizar las ramificaciones de este cambio con respecto a uniformity o non-invertibility, pero parece correcto siempre y cuando no tenga un hacker inteligente que intente omitir maliciosamente sus comprobaciones de suma de comprobación.
Tenga en cuenta que, debido al cambio anterior, esta implementación no dará los mismos resultados que las implementaciones verdaderas de la suma de comprobación de Fletcher (@MDBiker). Por lo tanto, no puede comparar la salida de esta función con la de Fletcher16 de Java, por ejemplo. Sin embargo, mostrará siempre devolverá el mismo resultado para la misma entrada (es determinista), por lo que puede comparar la salida de esta función en dos cadenas de texto.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:foo="my.foo.org">
<xsl:variable name="str1">The quick brown fox jumps over the lazy dog.</xsl:variable>
<xsl:variable name="str2">The quick frown box jumps over the hazy frog.</xsl:variable>
<xsl:template match="/">
Checksum 1: <xsl:value-of select="foo:checksum($str1)"/>
Checksum 2: <xsl:value-of select="foo:checksum($str2)"/>
</xsl:template>
<xsl:function name="foo:checksum" as="xs:int">
<xsl:param name="str" as="xs:string"/>
<xsl:variable name="codepoints" select="string-to-codepoints($str)"/>
<xsl:value-of select="foo:fletcher16($codepoints, count($codepoints), 1, 0, 0)"/>
</xsl:function>
<!-- can I change some xs:integers to xs:int and help performance? -->
<xsl:function name="foo:fletcher16">
<xsl:param name="str" as="xs:integer*"/>
<xsl:param name="len" as="xs:integer" />
<xsl:param name="index" as="xs:integer" />
<xsl:param name="sum1" as="xs:integer" />
<xsl:param name="sum2" as="xs:integer"/>
<xsl:choose>
<xsl:when test="$index gt $len">
<xsl:sequence select="$sum2 * 256 + $sum1"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="newSum1" as="xs:integer"
select="($sum1 + $str[$index]) mod 255"/>
<xsl:sequence select="foo:fletcher16($str, $len, $index + 1, $newSum1,
($sum2 + $newSum1) mod 255)" />
</xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>
La salida:
Checksum 1: 65256
Checksum 2: 25689
Nota sobre el uso: Usted dijo que necesitaba para funcionar suma de comprobación en "el contenido de un archivo XML En la raíz de esto es necesario comparar un texto. nodos ". Si pasa un nodo de texto a foo: suma de comprobación(), funcionará bien: se extraerá su valor de cadena.
FYI, ejecuté una prueba de rendimiento, para calcular la suma de comprobación de los nodos de texto en un archivo de entrada XML de 535KB. Aquí estaba la plantilla inicial que utilicé:
<xsl:template match="/">
Checksum of input: <xsl:value-of
select="sum(for $t in //text() return foo:checksum($t)) mod 65536"/>
</xsl:template>
Terminó en 0.8s, usando Saxon PE.
alternativa:
Si la cantidad de texto no es muy grande, probablemente sería más rápido y más preciso para comparar simplemente las propias cadenas (en lugar de sumas de control) entre sí. Pero tal vez no pueda obtener acceso a ambos nodos de texto al mismo tiempo, debido a las restricciones de su arquitectura ... No lo tengo claro por su descripción.
¿No puede copiar el XML fuera de XSL, digamos con MD5? – Oded
No puedo; el XSL es lo único sobre lo que tengo control. Este XSL básicamente se llama en el envío de formularios para generar un correo electrónico HTML. Como no hay forma de ir y consultar el enlace, el texto y la información de resumen, necesito analizarlo desde el XML devuelto. Sin embargo, podría haber cambiado el lado del cliente, así que tengo que encontrar una manera de comparar el texto devuelto con el hash de lo que inicialmente puse. – electrichead