2

当我尝试使用一个 SQLParameter 存储到 XML 类型的列中时,我遇到了 SQLParameter 问题。我正在创建 SqlDbType.Xml 的参数。似乎任何只有空白的 XML 元素都被转换为封闭元素。

这是相同的行为

SELECT CAST('<Cust><Fname>Andrew</Fname><Lname> </Lname></Cust>' as XML) 
VS 
SELECT CONVERT(xml, '<Cust><Fname>Andrew</Fname><Lname> </Lname></Cust>', 1)

我很惊讶地看到这是 SQLParameter 中的默认行为。有没有办法让 SqlDbType.Xml 的 SQLParameter 关心它的空白?在黑暗中拍摄时,我尝试将精度设置为 1,但这并没有帮助...

下面的代码在数据库中以这个结尾

<Cust><Fname>Andrew</Fname><Lname /></Cust>

如您所见,它去除了空白 XML 元素

// CREATE TABLE T(c1 int primary key, c2 xml)
static void Main(string[] args) {

using (var Connection = new System.Data.SqlClient.SqlConnection("Data Source=localhost;Initial Catalog=Test;Integrated Security=SSPI;"))
{
    Connection.Open();

    using (var Command = Connection.CreateCommand())
    {
      Command.CommandText = "INSERT INTO T VALUES (1, @s)";

      var XmlParameter = Command.Parameters.Add("s", System.Data.SqlDbType.Xml);
      XmlParameter.Value = "<Cust><Fname>Andrew</Fname><Lname>  </Lname></Cust>";

      Command.ExecuteNonQuery();
    }

    Connection.Close();
}

有谁知道解决它的方法,即不将参数解析为二进制并将其转换为插入/更新命令的一部分?

Command.CommandText = "INSERT INTO T VALUES (1, CONVERT(xml, @s, 1))";

任何帮助或反馈将不胜感激。

4

1 回答 1

1

如果您从外部源接收 XML 并且它只是从元素开始,您可以在字符串前面加上

<?xml version="1.0"?>
<!DOCTYPE Cust [
<!ATTLIST Cust xml:space (preserve) #FIXED 'preserve'>
]>

这应该使整个文档(Cust 根节点向下)保留空白。如果您只对特定字段感兴趣,而不是 ATTLIST 说 Cust,为您想要保留空白的每个元素添加一个新的 ATTLIST。例如

<!ATTLIST Fname xml:space (preserve) #FIXED 'preserve'>
<!ATTLIST Lname xml:space (preserve) #FIXED 'preserve'>

同样,我没有尝试过使用 SQL 服务器(我只是无权访问),但是 IE 和 Chrome 中的 XML 处理器按预期将 xml:space="preserve" 添加到文档中,正如您所说的那样上面给了你你正在寻找的行为。这种方法无需对 XML 进行深度操作,您只需在文档的开头添加一些处理指令即可。

于 2012-08-21T10:33:08.230 回答