Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XSL对XML文件进行散列_Xml_Xslt_Hash - Fatal编程技术网

使用XSL对XML文件进行散列

使用XSL对XML文件进行散列,xml,xslt,hash,Xml,Xslt,Hash,我试图找到一种方法来“散列”XML文件的内容。根本原因是需要比较传递给文本节点的一些文本节点,以确保校验和相同。传入的文本节点已从表单提交返回,我需要确保它们没有更改(在合理范围内,排除冲突) 架构很糟糕,所以请不要问它!我被锁定在sharepoint的一个给定实现中,其中包含一些非常糟糕的自定义代码,我需要解决这些代码 是否有一个性能良好的校验和/哈希函数可以实现?我需要检查大约100个文本节点。听起来您需要一个文本节点。您是要求XSLT实现,还是仅仅要求算法 这里是一个C语言的例子,移植到X

我试图找到一种方法来“散列”XML文件的内容。根本原因是需要比较传递给文本节点的一些文本节点,以确保校验和相同。传入的文本节点已从表单提交返回,我需要确保它们没有更改(在合理范围内,排除冲突)

架构很糟糕,所以请不要问它!我被锁定在sharepoint的一个给定实现中,其中包含一些非常糟糕的自定义代码,我需要解决这些代码

是否有一个性能良好的校验和/哈希函数可以实现?我需要检查大约100个文本节点。

听起来您需要一个文本节点。您是要求XSLT实现,还是仅仅要求算法

这里是一个C语言的例子,移植到XSLT应该不是很难

更新:下面是对Fletcher校验和的XSLT2.0修改。它是否足够快,取决于数据的大小和您拥有的时间。我很想知道你的测试进展如何。为了优化,我将尝试将
xs:integer
更改为
xs:int

注意,我已经用普通加法替换了我上面链接的实现的按位OR(
|
)。我没有资格分析这一变化对or的影响,但只要你没有一个聪明的黑客试图恶意绕过你的校验和检查,这似乎没问题

请注意,由于上述更改,此实现不会给出与Fletcher校验和(@MDBiker)的真正实现相同的结果。例如,您无法将此函数的输出与Java的Fletcher16的输出进行比较。但是,它将始终为相同的输入返回相同的结果(它是确定的),因此您可以在两个文本字符串上比较此函数的输出

<?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>
用法说明:您说过需要对“XML文件的内容”运行校验和,其根源是需要比较一些文本节点。如果将文本节点传递给foo:checksum(),它将正常工作:将提取其字符串值

仅供参考,我运行了一个性能测试,以计算535KB XML输入文件中文本节点的校验和。以下是我使用的初始模板:

<xsl:template match="/">
    Checksum of input: <xsl:value-of
      select="sum(for $t in //text() return foo:checksum($t)) mod 65536"/>    
</xsl:template>

输入校验和:
它使用萨克森PE在0.8秒内完成

或者:


如果文本量不是很大,那么简单地比较字符串本身(而不是校验和)可能会更快更准确。但由于您的体系结构限制,您可能无法同时访问两个文本节点。。。从您的描述中,我不清楚这一点。

您不能在XSL之外(比如使用MD5)散列XML吗?我不能;XSL是我唯一能控制的东西。此XSL基本上在表单提交时被调用,以生成HTML电子邮件。由于无法查询链接、文本和抽象信息,我需要从返回的XML中解析它。但是,它可能已在客户端更改,因此我需要找到一种方法,将返回的文本与我最初输入的哈希值进行比较。@electrichead:希望确保您看到我添加了一个实现。顺便说一句,对于可能感兴趣的人,我尝试将choose when Others更改为XPath only“if…then…else…”. 我想这可能会让它更快。为了使它工作,我必须使用一个单例“for”语句绑定
$newSum1
。结果是:在我的性能测试中始终是0.9秒,而不是0.8秒。实现中有一个bug。对于由单个字符组成的任何字符串,函数将返回“0”。为了考虑最后一个字符,我们必须将
xsl:when
子句的条件从
$index ge$len
更改为
$index gt$len
@serhiy.h:感谢您捕捉到这一点。修好了。(差不多3年后!)
<xsl:template match="/">
    Checksum of input: <xsl:value-of
      select="sum(for $t in //text() return foo:checksum($t)) mod 65536"/>    
</xsl:template>