我正在将一些 XML 数据插入 SQL Server 中的 XML 列,但在插入数据后,它已被 sql server 更改。这是我插入的数据
<xsl:value-of select="name/n/given" />
<xsl:text> </xsl:text>
<xsl:value-of select="name/n/family" />
Run Code Online (Sandbox Code Playgroud)
当我读回来时,它看起来像这样
<xsl:value-of select="name/n/given" />
<xsl:text />
<xsl:value-of select="name/n/family" />
Run Code Online (Sandbox Code Playgroud)
注意第二行。这是一个问题,因为它改变了 XSLT 转换输出的方式。第一个例子将在给定和姓氏之间创建一个空格,而第二个不会创建任何空格,所以它会像约翰约翰森,而第一个会像约翰约翰森。
有没有办法解决这个问题?
Mik*_*son 25
您可以xml:space = "preserve"
在要保留空间的节点上使用。使用 xml:space 是“只是一种意图信号”,但 SQL Server 在这里对我们很好。
对于一个节点
declare @X xml =
'<root>
<element xml:space = "preserve"> </element>
<element> </element>
</root>'
select @X;
Run Code Online (Sandbox Code Playgroud)
结果:
<root>
<element xml:space="preserve"> </element>
<element />
</root>
Run Code Online (Sandbox Code Playgroud)
整个文件:
declare @X xml =
'<root xml:space = "preserve">
<element> </element>
<element> </element>
</root>'
select @X;
Run Code Online (Sandbox Code Playgroud)
结果:
<root xml:space="preserve">
<element> </element>
<element> </element>
</root>
Run Code Online (Sandbox Code Playgroud)
整个文档的另一个选项是使用convert with style 1。
保留微不足道的空白。此样式设置设置默认 xml:space 处理以匹配 xml:space="preserve" 的行为。
declare @X xml = convert(xml,
'<root>
<element> </element>
<element> </element>
</root>', 1)
select @X;
Run Code Online (Sandbox Code Playgroud)
SQL Server 文档的这一页说
数据存储在一个内部表示中......可能不是文本 XML 的相同副本,因为没有保留以下信息:无关紧要的空格、属性顺序、命名空间前缀和 XML 声明。
对于您的示例,我认为它认为中间标签的空白不重要,因此可以自由地重构表示。我认为没有办法解决这个问题。这正是 SQL Server 实现 XML 数据类型的方式。
解决方法将包括使用占位符而不是@Aaron 所说的空格。消费者必须记住插入和删除这些令牌。或者将列定义为 nvarchar 而不是 XML。这肯定会保留所有空白和任何其他格式。一个简单的例子:
create table x(i nvarchar(99), j xml);
insert x values ('<a> </a>', '<a> </a>'); -- note the space
select * from x
i j
---------- -------
<a> </a> <a />
Run Code Online (Sandbox Code Playgroud)
nvarchar 列保留输入格式,而 XML 列不保留。
您将无法在 SQL 查询中使用 XPATH。如果 XML 仅在应用程序中被分解,这无关紧要。此外,字符串可以被压缩以节省数据库中的空间,如果这对您很重要。