49

Ich bin auf der Suche nach einer Möglichkeit mit C#, die ich eine Klasse in XML serialisieren und einen Namespace hinzufügen kann, aber das Präfix definieren, das diesen Namespace verwenden wird.XML-Serialisierung und Namespace-Präfixe

Letztlich Ich versuche, die folgende XML zu generieren: mit

<myNamespace:Node xmlns:myNamespace="..."> 
    <childNode>something in here</childNode> 
</myNamespace:Node> 

Ich kenne sowohl die DataContractSerializer und die XmlSerializer ich einen Namensraum hinzufügen kann, aber sie scheinen einen Präfix intern, mit etwas zu erzeugen, die ich kann nicht kontrollieren. Kann ich es mit einem dieser Serialisierer steuern (ich kann beide verwenden)?

Wenn ich nicht in der Lage bin, die Generierung der Namespaces zu steuern, muss ich meinen eigenen XML-Serializer schreiben, und wenn ja, wofür ist es am besten?

Antwort

84

Verwenden Sie XmlSerializerNamespaces, um den Namespace-Alias ​​zu steuern.

[XmlRoot("Node", Namespace="http://flibble")] 
public class MyType { 
    [XmlElement("childNode")] 
    public string Value { get; set; } 
} 

static class Program 
{ 
    static void Main() 
    { 
     XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
     ns.Add("myNamespace", "http://flibble"); 
     XmlSerializer xser = new XmlSerializer(typeof(MyType)); 
     xser.Serialize(Console.Out, new MyType(), ns); 
    } 
} 

Wenn Sie den Namespace zur Laufzeit ändern müssen, können Sie zusätzlich XmlAttributeOverrides verwenden.

+4

+1 aber könnte ich vorschlagen, eine Bearbeitung, um es klar zu machen, dass der erste Parameter in der .Add-Methode der Ort ist, wo die Magie geschieht, um das Präfix zu setzen. Es war mir aus der Antwort nicht klar, bis ich die MSDN-Dokumente überprüft habe. –

+0

gerecht zu werden, dass es keine Entsprechung mit DataContractSerializer gibt? (Ich möchte nur meine Optionen offen halten) –

+0

@Slace - Ja, ich glaube, es ist sicher anzunehmen, dass es ** kein Äquivalent für DCS gibt. Letztendlich ist DCS nicht dazu gedacht, Ihnen viel Kontrolle über die Ausgabe zu geben (wenn Sie die XML steuern wollen, benutzen Sie 'XmlSerializer' - das ist ihre Aufgabe). –

3

Wenn generierter Code aus einem Schema verwendet wird, in dem die Typen Namespaces haben, gilt diese Namespace-Überschreibung auf der Stammebene, aber bei den Tags innerhalb verschiedener Typen wird der Namespace der Klasse zugeordnet.

Ich hatte eine Gelegenheit, zwei verschiedene generierte Klassen zu verwenden, aber unterschiedliche Namensräume basierend darauf, auf welchem ​​Server ich sprach (fragen Sie nicht, nicht unter meiner Kontrolle).

Ich habe alle Overrides, die hier angeboten werden, ausprobiert und schließlich aufgegeben und eine Art Brute-Force-Methode verwendet, die wirklich gut funktioniert hat. Was ich getan habe, war Serialisierung zu einer Zeichenfolge. Verwenden Sie dann string.replace, um die Namespaces zu ändern, und senden Sie dann den Stream mit einem Zeichenfolgenbezeichner aus der Zeichenfolge. Gleiches für die Antwort - Aufnahme in einen String - manipulieren Sie den Namespace und deserialisieren Sie dann den String von einem Zeichenkettenschreiber.

Es kann nicht elegant sein oder alle ausgefallenen Übersteuerungen verwenden, aber es hat die Arbeit erledigt.