如何将字符串转换为SqlXml

11

我有一个返回格式正确的XML 字符串的方法。如何将该字符串转换为SqlXml类型?


这个链接可能会解决你的问题。https://dev59.com/6EbRa4cB1Zd3GeqP2aU0 - user1522920
5个回答

13

在纯C#中的另一种方式 - 为了后世记录:

using (var memoryStream = new MemoryStream())
{
    using (var xmlWriter = XmlWriter.Create(memoryStream))
    {
        xmlWriter.WriteString(xmlData.ToString().Trim());
        return new System.Data.SqlTypes.SqlXml(memoryStream);
    }
}

1
你的代码对我来说没有起作用,但是让我找到了正确的方向。你使用的xmlData的值是多少?我添加了我的版本的转换代码作为备选答案。 - R. Schreurs
当我尝试写出XML数据时,遇到了一个问题,即使用单引号而不是双引号来封装属性值。xmlWriter.WriteString失败并生成有关无效XML的错误。实际上,我不得不使用R. Schreurs的代码来解决这个问题。老实说,我不得不将其转换为SqlXml类型,而不仅仅使用字符串的原因是SQL Server也无法处理单引号和双引号。我完全不怪代码,只是其中一件事情对我不起作用。 - Nick Bork

10

我知道这个问题已经被回答过了,但是这些答案似乎都不适用于我。相反,我采用了另一种方法,使用了这个单行代码:

var sqlXml = new SqlXml(new XmlTextReader(new StringReader(stringToParseToSqlXml)));

然而这会导致内存泄漏,但将代码改为以下内容可以解决:

using (var reader = new StringReader(stringToParseToSqlXml))
{
    using (var xmlreader = new XmlTextReader(reader))
    {
        var sqlXml = new SqlXml(xmlreader);
        // Do other stuff
    }
}

我使用过这个,对我来说似乎有效。


谢谢,我也一直收到“closed object”消息。另外,我喜欢使用重构。 - DubMan

7
这是我编写的C#转换方法的版本。
public static SqlXml ConvertString2SqlXml(string xmlData)
{
    UTF8Encoding encoding = new UTF8Encoding();
    MemoryStream m = new MemoryStream(encoding.GetBytes(xmlData));
    return new SqlXml(m);
}

我对此并不满意,因为我希望使用using块来使用MemoryStream,但这给了我以下错误信息:

无法访问已释放对象。对象名:“在流关闭时调用Read的尝试无效。”。

我愿意接受这个问题,因为这段代码仅用于单元测试,我想测试一个具有SqlXml参数的SqlFunction,该函数将部署到SQL Server CLR。

ReinhardtB的答案对我没有用,因为存在以下问题:

当使用xmlData "<?xml version=\"1.0\" encoding=\"utf-8\"?><test></test>"(反斜杠在C#字符串文字中)调用时,我得到了以下错误信息:

System.InvalidOperationException occurred Message=Token Text in state Start would result in an invalid XML document. Make sure that the ConformanceLevel setting is set to ConformanceLevel.Fragment or ConformanceLevel.Auto if you want to write an XML fragment.

这很容易通过以下修改解决:

XmlWriterSettings settings = new XmlWriterSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (var xmlWriter = XmlWriter.Create(memoryStream, settings))

然而,这导致了以下异常:

System.ObjectDisposedException发生了 Message=无法访问已释放对象。对象名称:“调用已关闭流的Read的无效尝试”。Source=System.Data

我可以通过省略MemoryStream的using块(这当然是个坏主意)来解决这个问题,但随后又遇到了下一个问题:在检查SqlXml的值SqlXml.Value时,我发现它包含了&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;test&gt;&lt;/test&gt; 的值,也就是说,<和>已被转义!这看起来像是SqlXml类型的严重问题。

比 "var sqlXml = new SqlXml(new XmlTextReader(new StringReader(stringToParseToSqlXml)));" 更快。 - elle0087

3
在SQL Server中,一个简单的转换方法是: CAST(MyVarcharString AS xml) 或者在.NET中将其分配给SQLDbType.Xml,例如作为参数。

@TonyP:已更新包含SQLDbType.Xml信息。 - gbn
我不太熟悉以下代码,有什么建议吗? sxml = b.BaanSession(sxml); SqlParameter p = new SqlParameter("@x", SqlDbType.Xml); p.Value = sxml; xmsg =(SqlXml) p.Value; - TonyP
这个通常可以工作,但我们收到并尝试解析的 XML 使用单引号而不是双引号来封装节点属性,当使用 CAST 和 CONVERT 时会抛出异常。 - Nick Bork

1

如果设置正确的长度,SqlParameter可以很好地工作。

comm.Parameters.Add("@XML_Field", SqlDbType.Xml, stringXml.Length)
comm.Prepare()
comm.Parameters("@XML_Field").Value = stringXml

如果您希望在某些情况下设置DBNull.Value,则为-1:

comm.Parameters.Add("@XML_Field", SqlDbType.Xml, -1)
comm.Prepare()
comm.Parameters("@XML_Field").Value = DBNull.Value

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接