2010-05-14 34 views
6

tengo que crear un archivo XML con todos los elementos prefijados, como esto:XmlSerializer Producir XML Con Sin namespace prefix

<ps:Request num="123" xmlns:ps="www.ladieda.com"> 
    <ps:ClientId>5566</ps:ClientId> 
<ps:Request> 

Cuando i serializar mi objeto, C# es inteligente y tiene esto:

<Request num="123" xmlns="www.ladieda.com"> 
    <ClientId>5566</ClientId> 
<Request> 

Eso es bueno, porque el ps: no es necesario.

¿Pero hay una forma de forzar a C# a serializar todos los prefijos?

Mi código de serialización es esto (por objeto entrante pObject):

String XmlizedString = null; 
MemoryStream memoryStream = new MemoryStream(); 
XmlSerializer xs = new XmlSerializer(pObject.GetType()); 
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); 

xs.Serialize(xmlTextWriter, pObject); 
memoryStream = (MemoryStream)xmlTextWriter.BaseStream; 
XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray()); 
return XmlizedString; 


private String UTF8ByteArrayToString(Byte[] characters) 
{ 
    UTF8Encoding encoding = new UTF8Encoding(); 
    String constructedString = encoding.GetString(characters); 
    return (constructedString); 
} 
+0

Por cierto, no es olvidar el espacio de nombres. Su espacio de nombre está correctamente serializado. Simplemente no usa un prefijo, lo cual tiene sentido, ya que no le dijiste un prefijo para usar. –

Respuesta

15

En primer lugar, si el consumidor de la cadena de procesamiento de XML fueron, entonces ellos no se preocupan por el prefijo, ya que doesn no importa (a XML). Quizás no entienden XML y piensan que están procesando una cadena (que podría necesitar la cadena "ps:" en cada elemento).

En segundo lugar, usted debe cambiar su código un poco:

XmlSerializer xs = new XmlSerializer(pObject.GetType()); 
using (MemoryStream memoryStream = new MemoryStream()) 
{ 
    XmlWriterSettings settings = new XmlWriterSettings() 
    { 
     Encoding = Encoding.UTF8 
    }; 
    using (XmlWriter writer = XmlWriter.Create(memoryStream, settings)) 
    { 
     xs.Serialize(writer, pObject); 
    } 
    return Encoding.UTF8.GetString(memoryStream.ToArray()); 
} 

Esto disponer adecuadamente de la corriente y XmlWriter si se produce una excepción, deja de usar la clase XmlTextWriter obsoleta, y aún así devuelve una cadena que contiene XML escrito para UTF-8.

Por último, para controlar el prefijo, consulte "How to: Qualify XML Element and XML Attribute Names":

XmlSerializerNamespaces myNamespaces = new XmlSerializerNamespaces(); 
myNamespaces.Add("ps", "www.ladieda.com"); 

XmlSerializer xs = new XmlSerializer(pObject.GetType()); 
using (MemoryStream memoryStream = new MemoryStream()) 
{ 
    XmlWriterSettings settings = new XmlWriterSettings() 
    { 
     Encoding = Encoding.UTF8 
    }; 
    using (XmlWriter writer = XmlWriter.Create(memoryStream, settings)) 
    { 
     xs.Serialize(writer, pObject, myNamespaces); 
    } 
    return Encoding.UTF8.GetString(memoryStream.ToArray()); 
} 
+2

+1 excelente respuesta: excelentes explicaciones y buenas muestras de código fáciles de seguir. –

+0

¡Genial! ¡Esto funciona de la caja! Gracias amigo. – Michel

+0

Muy extraño: este código produce un carácter no visible (en el depurador) como primer carácter de la cadena xml. Solo aparece si lo compara con la misma cadena sin este carácter, o si lo html.encode, porque el carácter no visible sí se codifica. Solo tiene 1 char, y la solución hasta ahora es quitárselo. – Michel

0

También puedes ver XmlNamespaceDeclarationsAttribute. Advertencia: al deserializarlo, solo le dará espacios de nombres definidos por ese elemento, no tendrá espacios de nombres definidos en elementos principales. Si no tiene un tipo de raíz consistente, use la sobrecarga XmlSerializer.Serialize() de @ John Saunders.

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlnamespacedeclarationsattribute.aspx

En otra pregunta @ John Saunders sugiere el uso de este atributo en lo que respecta a xmlns controlan en WSDL: Namespace Prefixes in Wsdl (.net)

De MSDN muestra:

// C# 
using System; 
using System.IO; 
using System.Xml.Serialization; 
[XmlRoot("select")] 
public class Select { 
    [XmlAttribute] public string xpath; 
    [XmlNamespaceDeclarations] public XmlSerializerNamespaces xmlns; 
} 
public class Test { 
    public static void Main(string[] args) { 
     Select mySelect = new Select(); 
     mySelect.xpath = "myNS:ref/@common:y"; 
     mySelect.xmlns = new XmlSerializerNamespaces(); 
     mySelect.xmlns.Add("MyNS", "myNS.tempuri.org"); 
     mySelect.xmlns.Add("common", "common.tempuri.org"); 
     XmlSerializer ser = new XmlSerializer(typeof(Select)); 
     ser.Serialize(Console.Out, mySelect); 
    } 
} 
// Output: 
// <?xml version="1.0" encoding="IBM437"?> 
// <select xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmln:xsi="http://www.w3.org/2001/XMLSchema-instance" 
// xmlns:common="common.tempuri.org" xmlns:MyNS="myNS.tempuri.org" xpath="myNS:ref/@common:y" /> 
Cuestiones relacionadas