2012-04-18 19 views
15

Estoy tratando de comunicarme con un procesador de pagos. Cuando uso XmlSerializer.Serialize en mi objeto consigoXmlSerializer.Serialize Eliminación de la etiqueta <xml>

<?xml version=\"1.0\" encoding=\"utf-16\"?> 
<txn xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"> 
    <ssl_merchant_id>xxxxxx</ssl_merchant_id> 
    <ssl_user_id>xxxxxx</ssl_user_id> 
    <ssl_pin>xxxxxx</ssl_pin> 
    <ssl_test_mode>True</ssl_test_mode> 
    <ssl_transaction_type>ccavsonly</ssl_transaction_type> 
    <ssl_card_number>4111111111111111</ssl_card_number> 
    <ssl_exp_date>0612</ssl_exp_date> 
    <ssl_avs_address>101 Main St.</ssl_avs_address> 
    <ssl_avs_zip>90210</ssl_avs_zip> 
</txn> 

Antes de utilizar este método, he construido manualmente el XML para la prueba y esto funcionó:

<txn> 
    <ssl_merchant_id>xxxxxx</ssl_merchant_id> 
    <ssl_user_id>xxxxxx</ssl_user_id> 
    <ssl_pin>xxxxxx</ssl_pin> 
    <ssl_test_mode>True</ssl_test_mode> 
    <ssl_transaction_type>ccavsonly</ssl_transaction_type> 
    <ssl_card_number>4111111111111111</ssl_card_number> 
    <ssl_exp_date>0612</ssl_exp_date> 
    <ssl_avs_address>101 Main St.</ssl_avs_address> 
    <ssl_avs_zip>90210</ssl_avs_zip> 
</txn> 

¿Cómo hago para despojar a la <?xml version=\"1.0\" encoding=\"utf-16\"?> y xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"> del XML o no tienen el serializador generarlo para comenzar?

Mi objeto que parece:

[XmlRoot(ElementName="txn")] 
public class AvsTransmission 
{ 
    [XmlElement] 
    public string ssl_merchant_id { get; set; } 
    [XmlElement] 
    public string ssl_user_id { get; set; } 
    [XmlElement] 
    public string ssl_pin { get; set; } 
    [XmlElement] 
    public string ssl_test_mode { get; set; } 
    [XmlElement] 
    public string ssl_transaction_type { get; set; } 
    [XmlElement] 
    public string ssl_card_number { get; set; } 
    [XmlElement] 
    public string ssl_exp_date { get; set; } 
    [XmlElement] 
    public string ssl_avs_address { get; set; } 
    [XmlElement] 
    public string ssl_avs_zip { get; set; } 
} 

Respuesta

28

Mi primera respuesta fue sólo la mitad del problema, también tiene que quitar la declaración como se ha mencionado.

Aquí se muestra un ejemplo:

XmlWriterSettings settings = new XmlWriterSettings(); 
settings.OmitXmlDeclaration = true; 

MemoryStream ms = new MemoryStream(); 
XmlWriter writer = XmlWriter.Create(ms, settings); 

XmlSerializerNamespaces names = new XmlSerializerNamespaces(); 
names.Add("", ""); 

XmlSerializer cs = new XmlSerializer(typeof(Cat)); 

cs.Serialize(writer, new Cat { Lives = 9 }, names); 

ms.Flush(); 
ms.Seek(0, SeekOrigin.Begin); 
StreamReader sr = new StreamReader(ms); 
var xml = sr.ReadToEnd(); 

La cadena xml ahora contiene:

<cat><Lives>9</Lives></cat> 
+0

Gracias, lo veré mañana. –

+0

Técnicamente, agregar un prefijo vacío y un espacio de nombres como ese no es compatible (es decir, "comportamiento indefinido"). –

+0

@JeffMercado, ¿cómo obtener NO espacios de nombres? – payo

2

Si utiliza XmlWriter hay un ajuste de omitir la declaración http://msdn.microsoft.com/en-us/library/system.xml.xmlwritersettings.omitxmldeclaration.aspx

voy trabaje con un ejemplo, pero eso podría ser suficiente para que empiece.


EDIT: He aquí una muestra que se ejecuta en LINQPad

string test = "test"; 
XmlWriterSettings settings = new XmlWriterSettings(); 
settings.OmitXmlDeclaration = true; 
MemoryStream strm = new MemoryStream(); 
XmlWriter writer = XmlWriter.Create(strm, settings); 
XmlSerializer serializer = new XmlSerializer(typeof(string)); 
serializer.Serialize(writer, test); 
strm.Position = 0; 
StreamReader reader = new StreamReader(strm); 
var x = reader.ReadToEnd(); 
x.Dump(); 
writer.Close(); 
reader.Close(); 
strm.Close(); 

salida

<string>test</string>

como comentario la línea 3 y la salida es

<?xml version="1.0" encoding="utf-8"?><string>test</string>

+0

Gracias, lo veré mañana. –

0

Solo para simplificar la solución. del problema original de la eliminación de declaración de codificación UTF aquí es el código

   StringBuilder sb = new StringBuilder(); 
       var serializer = new System.Xml.Serialization.XmlSerializer(typeToSerialize.GetType()); 
       serializer.Serialize(System.Xml.XmlWriter.Create(sb, new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent=true }), typeToSerialize); 
5

Primera función de objeto convertir a cadena XML, el segundo objeto un convertido y escribir XML para presentar simultáneamente.

public static string Serialize<T>(T obj) 
    { 
     XmlWriterSettings settings = new XmlWriterSettings(); 
     settings.OmitXmlDeclaration = true; 
     var writer = new StringWriter(); 
     XmlWriter xmlWriter = XmlWriter.Create(writer, settings); 

     XmlSerializerNamespaces names = new XmlSerializerNamespaces(); 
     names.Add("", ""); 

     XmlSerializer serializer = new XmlSerializer(typeof(T)); 

     serializer.Serialize(xmlWriter, obj, names); 
     var xml = writer.ToString(); 
     return xml; 
    } 

    public static void Serialize<T>(T obj, string filepath) 
    { 
     XmlWriterSettings settings = new XmlWriterSettings(); 
     settings.OmitXmlDeclaration = true; 
     var writer = new StreamWriter(filepath); 
     XmlWriter xmlWriter = XmlWriter.Create(writer, settings); 

     XmlSerializerNamespaces names = new XmlSerializerNamespaces(); 
     names.Add("", ""); 

     XmlSerializer serializer = new XmlSerializer(typeof(T)); 

     serializer.Serialize(xmlWriter, obj, names); 
    } 

En realidad me di cuenta de que el código se repite. En estos métodos, cambie solo una cosa que sea el objeto del escritor, por lo que el código debe ser como a continuación. De esta forma, puede usar código fácilmente simplemente cambiando el tipo de objeto del escritor.

public static string Serialize<T>(T obj) 
    { 
     var writer = new StringWriter(); 
     Serialize<T>(obj,writer); 
     var xml = writer.ToString(); 
     return xml; 
    } 

    public static void Serialize<T>(T obj, string filepath) 
    { 
     var writer = new StreamWriter(filepath); 
     Serialize<T>(obj,writer); 
    } 

    public static void Serialize<T>(T obj, TextWriter writer) 
    { 
     XmlWriterSettings settings = new XmlWriterSettings(); 
     settings.OmitXmlDeclaration = true; 
     XmlWriter xmlWriter = XmlWriter.Create(writer, settings);    
     XmlSerializerNamespaces names = new XmlSerializerNamespaces(); 
     names.Add("", "");    
     XmlSerializer serializer = new XmlSerializer(typeof(T));    
     serializer.Serialize(xmlWriter, obj, names); 
    } 
0

muy similar a la respuesta orignal @ de payo:

Si desea eliminar el espacio de nombres que también puede querer quitar la versión, para ahorrarle la búsqueda He añadido que la funcionalidad por lo que el código de abajo se Haz ambos.

También lo envolví en un método genérico ya que estoy creando archivos xml muy grandes que son demasiado grandes para serializar en la memoria así que he roto mi archivo de salida y lo serializo en "trozos" más pequeños:

public string XmlSerialize<T>(T entity) where T : class 
{ 
    // removes version 
    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.OmitXmlDeclaration = true; 

    XmlSerializer xsSubmit = new XmlSerializer(typeof(T)); 
    StringWriter sw = new StringWriter(); 
    using (XmlWriter writer = XmlWriter.Create(sw, settings)) 
    { 
     // removes namespace 
     var xmlns = new XmlSerializerNamespaces(); 
     xmlns.Add(string.Empty, string.Empty); 

     xsSubmit.Serialize(writer, entity, xmlns); 
     return sw.ToString(); // Your XML 
    } 
} 
Cuestiones relacionadas