2010-02-26 15 views
49

Szukam sposobu z C#, który można serializować klasy na XML i dodać przestrzeń nazw, ale zdefiniować prefiks, który będzie używać tej przestrzeni nazw.Serializacja XML i przedrostki przestrzeni nazw

Ostatecznie Próbuję wygenerować następujące XML:

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

wiem, ze zarówno DataContractSerializer i XmlSerializer mogę dodać nazw, ale wydaje się, aby wygenerować prefiks wewnętrznie, z czymś, co ja "Nie jestem w stanie kontrolować. Czy jestem w stanie kontrolować to z którymś z tych serializerów (mogę użyć któregokolwiek z nich)?

Jeśli nie będę w stanie kontrolować generowania przestrzeni nazw, będę musiał napisać mój własny serializator XML, a jeśli tak, to na co go najlepiej napisać?

Odpowiedz

84

Aby kontrolować alias obszaru nazw, użyj XmlSerializerNamespaces.

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

Jeśli trzeba zmienić nazw przy starcie, można dodatkowo skorzystać XmlAttributeOverrides.

+4

+1 ale czy mogę zaproponować edycję, która sprawi, że będzie jasne, że pierwszym parametrem w metodzie .Add jest miejsce, w którym dzieje się magia ustawiania prefiksu. Odpowiedź nie była dla mnie jasna, dopóki nie sprawdziłem dokumentów MSDN. –

+0

uczciwie zakładać, że nie ma odpowiednika z DataContractSerializer? (Chcę tylko zachować otwarte opcje) –

+0

@Slace - tak, uważam, że można bezpiecznie założyć, że ** nie jest ** odpowiednikiem dla DCS. Ostatecznie, DCS nie ma na celu dać ci dużej kontroli nad wyjściem (jeśli chcesz kontrolować xml, użyj 'XmlSerializer' - to jest jego zadanie). –

3

Podczas korzystania z wygenerowanego kodu ze schematu, w którym typy mają przestrzenie nazw, to zastępowanie przestrzeni nazw ma zastosowanie na poziomie katalogu głównego, ale znaczniki należące do różnych typów będą miały przestrzeń nazw powiązaną z tą klasą.

Miałem okazję używać dwóch różnych wygenerowanych klas, ale mam różne przestrzenie nazw w zależności od tego, z którym serwerem rozmawiałem (nie pytaj, nie pod moją kontrolą).

Wypróbowałem wszystkie przesłonięcia oferowane tutaj i ostatecznie zrezygnowałem i użyłem pewnego rodzaju metody brutalnej siły, która faktycznie działała całkiem dobrze. To, co zrobiłem, to serializacja na ciąg znaków. Następnie użyj string.replace, aby zmienić przestrzenie nazw, a następnie opublikował strumień z łańcucha za pomocą napisu tekstowego. To samo z odpowiedzią - przechwyć do ciągu - manipuluj przestrzenią nazw, a następnie zserializuj ciąg znaków z pisarza napisów.

To może nie być eleganckie lub użyć wszystkich wymyślnych przesłonięć, ale wykonało to zadanie.