2010-05-14 5 views
6

Ich habe eine XML-Datei zu erstellen, mit allen Elementen voran, wie folgt aus:XmlSerializer Producing XML With No Namensraumpräfix

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

Wenn ich mein Objekt serialisiert, C# intelligent ist und tut dies:

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

Das ist gut, denn das ps: ist nicht notwendig.

Aber gibt es eine Möglichkeit, C# zu zwingen, alle Präfixe zu serialisieren?

Mein serialize Code ist dies (für eingehendes Objekt 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, ist es nicht Ihren Namensraum zu vergessen. Ihr Namespace ist korrekt serialisiert. Es verwendet einfach kein Präfix, was sinnvoll ist, da Sie ihm kein Präfix gegeben haben. –

Antwort

15

Vor allem, wenn die Verbraucher von der Zeichenfolge XML Material Verarbeitung, dann würden sie über das Präfix nicht kümmern, da es doesn Es ist egal (nach XML). Vielleicht verstehen sie XML nicht und denken, dass sie eine Zeichenfolge verarbeiten (die für jedes Element die Zeichenfolge "ps:" benötigt).

Zweitens, sollten Sie Ihren Code ein wenig ändern:

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

Dies wird ordnungsgemäß von dem Strom verfügen und XmlWriter, wenn eine Ausnahme ausgelöst wird, stoppt die veraltete XmlTextWriter-Klasse, und doch gibt noch ein Zeichenfolge mit XML, die für UTF-8 geschrieben wurde.

Schließlich, um das Präfix zu steuern, finden Sie "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 ausgezeichnete Antwort - großartige Erklärungen und gute, leicht zu befolgende Codebeispiele. –

+0

Großartig! Das funktioniert sofort! Danke Kumpel. – Michel

+0

Sehr seltsam: Dieser Code erzeugt ein (im Debugger) nicht sichtbares Zeichen als erstes Zeichen der XML-Zeichenkette. Es erscheint nur, wenn Sie es mit der gleichen Zeichenkette ohne dieses Zeichen vergleichen, oder wenn Sie es html.encode, weil das nicht sichtbare Zeichen kodiert wird. Es ist nur 1 Char, und die Workaround ist bis jetzt, um es abzustreifen. – Michel

0

Auch XmlNamespaceDeclarationsAttribute auszuchecken. Vorbehalt: Wenn Sie die Deserialisierung durchführen, erhalten Sie nur Namespaces, die von diesem Element definiert werden. In den übergeordneten Elementen sind keine Namespaces definiert. Wenn Sie keinen konsistenten Stammtyp haben, verwenden Sie die XmlSerializer.Serialize() - Überladung von @John Saunders.

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

In einer anderen Frage @ John Saunders dieses Attribut in Bezug auf die Steuerung Xmlns in WSDL schlägt mit: Namespace Prefixes in Wsdl (.net)

Von MSDN-Beispiel:

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