.net 在SQLServer中规范化XML以进行哈希

.net 在SQLServer中规范化XML以进行哈希,.net,xml,tsql,sql-server-2005,xml-parsing,.net,Xml,Tsql,Sql Server 2005,Xml Parsing,我问是谁让我做了以下事情 创建C对象结构的XML表示,以便将其传递给SQLServer。 创建一个存储过程,该过程对XML进行散列,然后将XML分解到相关表中,并将散列存储在根表中,以便快速查找。 这意味着我可以将复杂的对象数据传递给SQLServer,并对哈希进行查找,而不是尝试将XML分解并与表进行匹配,我也可以这样做,但速度较慢 然而,XML的一个优点是,您可以对其进行格式化,例如缩进等,而且属性顺序并不重要。但是当你散列一些东西时,格式化和缩进是很重要的。所以我在C中所做的是 通过按字母

我问是谁让我做了以下事情

创建C对象结构的XML表示,以便将其传递给SQLServer。 创建一个存储过程,该过程对XML进行散列,然后将XML分解到相关表中,并将散列存储在根表中,以便快速查找。 这意味着我可以将复杂的对象数据传递给SQLServer,并对哈希进行查找,而不是尝试将XML分解并与表进行匹配,我也可以这样做,但速度较慢

然而,XML的一个优点是,您可以对其进行格式化,例如缩进等,而且属性顺序并不重要。但是当你散列一些东西时,格式化和缩进是很重要的。所以我在C中所做的是

通过按字母顺序排列所有属性来规范XML 使用.toString IsableFormatting删除额外的格式空间 这很好,但是当我进行测试时,格式化XML更容易,这样我就可以更容易地看到传递给存储过程的内容

如果可以信任SQLServer来保持属性顺序,那就太好了

XML实例中属性的顺序不保留。当你 查询存储在XML类型列中的XML实例,顺序为 结果XML中的属性可能不同于原始XML 例如

这意味着我不能使用SQLServer的XML数据类型来规范化数据

让我烦恼的是,在某个时候,有人会使用我的进程,并且认为哦,太好了,XML,属性顺序不重要,格式不重要,表示的数据是相同的,但是,当我散列时,情况不会是这样

有人能解决这个问题吗?我真的不想用t-SQL编写XML解析器!!或者使用其他人编写的XML解析器对其进行规范化。为什么SQLServerXML数据类型不能只保留属性顺序


我想我可以相信我的应用程序总是以相同的格式/顺序传递XML,从而为相同的对象生成相同的哈希。但是我对存储过程也必须信任应用程序来完成这一任务的想法感到不舒服。我希望能够以某种方式检查XML的规范化,它显然会更加健壮。

我将尝试在存储过程中序列化对象

让我们上下面的课:

class MyCustomObject 
{
    int id;
    string SomeField;
}
然后可以使用存储过程,在该过程中,以xml序列化对象并计算输入参数的校验和,然后在另一个过程中,可以传递HashValuechecksum和xml。通过反序列化Xml,yo可以计算Xml中字段的校验和,并将其与传递的哈希值进行比较

请尝试以下代码: 注意,您应该存储哈希值并将其返回给调用者,然后对xml进行处理

CREATE PROCEDURE HashObject(@id int, @SomeField varchar(255)) AS
BEGIN
    SELECT
        CHECKSUM(@id, @SomeField) AS CalculatedHashValue,
        (SELECT @id AS ID, @SomeField AS SomeField FOR XML RAW('xmlRowName')) AS Xml_Data,
        @id AS SPCall_ID,
        @SomeField AS SPCall_SomeField
END
GO

CREATE PROCEDURE CheckHash(@HashValue INT, @data XML) AS
BEGIN
    SELECT  
        CHECKSUM(rt.value('@ID', 'int'), rt.value('@SomeField', 'varchar(255)')) AS Xml_CalculatedHashValue,
        @data Xml_Data,
        rt.value('@ID', 'int') AS Xml_ID,
        rt.value('@SomeField', 'varchar(255)') AS Xml_SomeField,
        @HashValue AS SPCall_HashValue

    FROM @data.nodes('xmlRowName') AS nd(rt)

END
GO

DECLARE @id INT = 11
DECLARE @SomeField varchar(255) = 'string value'
DECLARE @data XML

EXEC dbo.HashObject @id, @SomeField

SET @data = (SELECT @id AS ID, @SomeField AS SomeField FOR XML RAW('xmlRowName'))
EXEC dbo.CheckHash 0, @data

SET @data = (SELECT 25 AS ID, 'diferent string value' AS SomeField FOR XML RAW('xmlRowName'))
EXEC dbo.CheckHash 0, @data
GO  

尽管SQLServer解析/规范化过程的结果可能不会创建与c完全相同的XML,但至少是一致的。在对XML进行散列之前,您不能依靠这种一致性来处理它吗?@paul Well,就我的实际应用而言,是的。但是如果有人想知道某个特定的记录是否存在,并且他们用一些格式化的XML手动或从另一个应用程序调用proc,那么他们可能会认为它不存在,而实际上是这样,然后我可能会得到两个语义相同的记录,并使用不同的哈希值,这是我想要避免的。谢谢你的回答。我不确定我将如何将这个解决方案应用到我的情况中——我可以让我的内部元素重复任意次数。我需要将数据作为XML从.Net传递到SQLServer,但我希望属性顺序和格式与哈希值无关。