2011-01-31 14 views
10

Tengo un método que devuelve una cadena Xml bien formada. ¿Cómo transfiero esta cadena a SqlXml?Cómo lanzar una cadena a SqlXml

+0

Este enlace puede resolver su problema. http://stackoverflow.com/questions/574928/c-sql-whats-wrong-with-sqldbtype-xml-in-procedures –

Respuesta

2

En SQL Server, un simple: CAST(MyVarcharString AS xml)

O asignarlo al SQLDbType.Xml en .NET como, por ejemplo, un parámetro

+0

Lo siento, no dije que estoy hablando de C#, no t- sql .. – TonyP

+0

@TonyP: actualizado con SQLDbType.Xml información – gbn

+0

No me siento cómodo haciendo lo siguiente, cualquier consejo sxml = b.BaanSession (sxml); SqlParameter p = new SqlParameter ("@ x", SqlDbType.Xml); p.Value = sxml; xmsg = (SqlXml) p.Value; – TonyP

12

Otra forma en C# puro - para la posteridad:

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

Su código no funcionó para mí, pero me puso en el camino correcto. ¿Cuál es el valor de xmlData que funcionó para ti? Agregué mi versión del código de conversión como una respuesta alternativa. –

+0

Tuve un problema con este código cuando los datos XML que intentaba escribir usaban una comilla simple para encapsular valores de atributo en lugar de una comilla. El xmlWriter.WriteString falló y generó un error sobre XML no válido. De hecho, tuve que usar el código de R. Schreurs para resolver el problema. Honestamente, la razón por la que tuve que convertir a un tipo de SqlXml en lugar de simplemente usar una cadena es que SQL Server también se estaba ahogando en comillas simples vs. comillas. No fallo en absoluto el código, solo una de esas cosas en las que esto no funcionó para mí. –

7

Esta es mi versión de un método de conversión C#.

public static SqlXml ConvertString2SqlXml(string xmlData) 
{ 
    UTF8Encoding encoding = new UTF8Encoding(); 
    MemoryStream m = new MemoryStream(encoding.GetBytes(xmlData)); 
    return new SqlXml(m); 
} 

no estoy muy agradecidos con él, porque me hubiera gustado tener la MemoryStream con un bloque usando, pero eso me dio:

no pueden acceder a un objeto desechado. Nombre del objeto: 'Invalid attempt to call Read when the stream is closed.'.

Estoy dispuesto a aceptar esa cuestión, ya que este código sólo se utiliza en unidad de pruebas, en el que necesito para probar una SqlFunction con un parámetro SqlXml, que se implementa en el CLR de SQL Server.

La respuesta de ReinhardtB no funcionó para mí, debido a las siguientes cuestiones: Cuando se llama a esto con xmlData "<?xml version=\"1.0\" encoding=\"utf-8\"?><test></test>" (las barras invertidas están en el # cadena literal C), que tengo:

sistema. InvalidOperationException se produjo Message = Token Text en el estado Start daría como resultado un documento XML no válido. Asegúrese de que la configuración ConformanceLevel esté establecida en ConformanceLevel.Fragment o ConformanceLevel.Auto si desea escriba un fragmento XML.

Este fue fácilmente fijado por la siguiente modificación:

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

Sin embargo, esto llevó a la siguiente excepción:

System.ObjectDisposedException ocurrió Mensaje = No se puede acceder a un objeto desechado . Nombre del objeto: 'Intento inválido de invocar a Read cuando la corriente está cerrada.'. Fuente = System.Data

esto, pude trabajar en torno al omitir el uso de bloques para el MemoryStream (que por supuesto es una mala idea), sólo para golpear el próximo número: al inspeccionar el valor de SqlXml, SqlXml.Value, encontré que contiene el valor &lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;test&gt;&lt;/test&gt;, es decir, < y> se han escapado! Esto parece un problema grave con el tipo SqlXml.

+0

más rápido que "var sqlXml = new SqlXml (new XmlTextReader (new StringReader (stringToParseToSqlXml)));" – elle0087

1

El parámetro SqlParameter funciona bien si establece la longitud correcta.

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

Y -1 si desea establecer DBNull.Valor en algunos casos:

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

Sé que esto ha sido respondido, pero ninguna de las respuestas pareció funcionar para mí. En lugar Tomé otro enfoque que utiliza este oneliner

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

Sin embargo, esto tiene una fuga, pero cambiando a:

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

He utilizado este, y parece que funciona para mí.

+0

Gracias, constantemente recibía el mensaje de objeto cerrado también. También me gusta usar el refactor. – DubMan

Cuestiones relacionadas