2010-05-14 13 views
6

devo creare un file XML con tutti gli elementi come prefisso, come questo:XmlSerializer Producing XML With No Namespace Prefix

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

Quando ho serializzare il mio scopo, C# è intelligente e fa questo:

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

Questo è buono, perché la ps: non è necessario.

Ma c'è un modo per forzare C# per serializzare tutti i prefissi?

Il mio codice serialize è questo (per oggetto in entrata 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

BTW, non è dimenticare lo spazio dei nomi. Il tuo spazio dei nomi è serializzato correttamente. Semplicemente non sta usando un prefisso, il che ha senso, dal momento che non gli hai detto un prefisso da usare. –

risposta

15

Prima di tutto, se il consumatore della stringa sono stati elaborazione XML, poi sarebbero non si preoccupano il prefisso, dal momento che doesn importa (a XML). Forse non capiscono l'XML e pensano che stiano elaborando una stringa (che potrebbe richiedere la stringa "ps:" su ogni elemento).

In secondo luogo, si dovrebbe modificare il codice un po ':

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()); 
} 

Ciò smaltire il flusso e XmlWriter se viene generata un'eccezione, si ferma utilizzando la classe XmlTextWriter deprecato, ma restituisce comunque un stringa contenente XML scritto per UTF-8.

Infine, per controllare il prefisso, vedi "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 eccellente risposta - grandi spiegazioni e buoni esempi di codice facili da seguire. –

+0

Ottimo! Funziona fuori dalla scatola! Grazie compagno. – Michel

+0

Molto strano: questo codice produce un carattere non visibile (nel debugger) come primo carattere della stringa xml. Si apre solo se lo si confronta con la stessa stringa senza questo carattere, o se lo si html.encode, perché il carattere non visibile viene codificato. È solo 1 carattere, e il rimedio finora è di toglierlo. – Michel

0

controllare anche XmlNamespaceDeclarationsAttribute. Avvertenza: durante la deserializzazione fornirà solo spazi dei nomi definiti da quell'elemento, non avrà spazi dei nomi definiti negli elementi padre. Se non si dispone di un tipo di root coerente, utilizzare l'overload XmlSerializer.Serialize() da @John Saunders.

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

In un'altra domanda @ John Saunders suggerisce di utilizzare questo attributo per quanto riguarda xmlns di controllo in WSDL: Namespace Prefixes in Wsdl (.net)

Da MSDN Esempio:

// 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" /> 
Problemi correlati