SQL Server 2012 XML 类型保留重要的空格

本文关键字:保留 重要的 空格 类型 XML Server 2012 SQL | 更新日期: 2023-09-27 18:31:22

我正在尝试将一些数据存储在XML类型列中,当数据为字符串时,该列将保留确切的文本,并且不会替换或调整嵌入的行尾,特别是CR和LF。

因此,像"A''r'B''rC'D"这样的 C# 字符串需要完全如此返回,但 XML 转换似乎坚持将这些行尾替换为 LF,这实际上会损坏数据。我知道为什么在读取 Xml 文件等时会发生这种规范化,但这不是一个文件,空格很重要。

我试过转换(xml, N'', 1);

我尝试将xml:space="preserve"作为包含数据的元素的属性添加。

我试过使用 &# x D ; 代替 CR

对于背景:

我正在使用CONVERT(varbinary(max), Value)检查字符串的内容,然后将输出复制到 TextPad,以便我可以准确找到并查看存储的字符。

我有理由确定数据在结尾不变的情况下到达 SQL Server(我正在使用带有 NewLineHandling = NewLineHandling.None 的 XmlWriter 设置,LLBLGen 将数据视为字符串),但不确定,因为复制和粘贴会更改结尾,所以我无法检查它们。

Xml 序列化代码基本上是包装字典

    void IXmlSerializable.WriteXml(XmlWriter writer)
    {
        var list = new List<Entry>(Values.Count);
        foreach (var entry in Values)
        {
            list.Add(new Entry(entry.Key, entry.Value));
        }
        MementoXmlSerializer.Serialize(writer, list);
    }
    [XmlType("Entry")]
    public struct Entry
    {
        public Entry(string key, object value): this()
        {
            Key = key;
            Value = value;
        }
        [XmlAttribute("key")]
        public string Key { get; set; }
        [XmlElement("Value")]
        public object Value { get; set; }
    }

其中 MementoSerializer 定义为:-

static readonly Type[] AdditionalTypes =
{
    typeof(int[]),
    typeof(string[])
};
static readonly XmlSerializer MementoXmlSerializer = new XmlSerializer(typeof(List<Entry>), null, AdditionalTypes, new XmlRootAttribute("Entries"), null);

LLBLGen 使用的模式和在 Sql Server Profiler 中看到的模式如下所示:

declare @p3 xml
set @p3=convert(xml,N'<Entries xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Entry key="FirmName"><Value xsi:type="xsd:string">A
B
C
D</Value></Entry></Entries>')
exec sp_executesql N'UPDATE [TIPS].[dbo].[Memento] SET [Value]=@p1 WHERE ( [TIPS].[dbo].[Memento].[ID] = @p2)',N'@p1 xml,@p2 int',@p1=@p3,@p2=4

任何帮助表示赞赏。

SQL Server 2012 XML 类型保留重要的空格

看起来由SqlDataReader创建的SqlXml

和SqlXmlStreamWrapper实例(至少在.Net 4.0中)无法更改它们如何解码Sql Server返回的二进制XML数据的任何设置。

二进制数据肯定在客户端正确接收,因为缓冲区的十六进制转储显示:

4100 0D00 0A00 4200 0D00 4300 0A00 4400

我暂时放弃了拥有xpath可搜索纪念品的想法。这本来是一个不错的选择,但我不能让我的数据不可靠地往返。

我将值列类型更改回NVARCHAR(MAX),现在一切正常。