.NET'te bir nesneyi serileştirirken tüm xsi ve xsd ad alanlarını atlamak mı?


132

Kod şuna benzer:

StringBuilder builder = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
using (XmlWriter xmlWriter = XmlWriter.Create(builder, settings))
{
    XmlSerializer s = new XmlSerializer(objectToSerialize.GetType());
    s.Serialize(xmlWriter, objectToSerialize);
}

Ortaya çıkan serileştirilmiş belge, aşağıdaki gibi ad alanlarını içerir:

<message xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 
    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" 
    xmlns="urn:something">
 ...
</message>

Xsi ve xsd ad alanlarını kaldırmak için, xmlns = ”…” almadan bir nesneyi XML'e nasıl serileştirebilirim? .

Mesaj etiketimi olarak istiyorum <message>(herhangi bir ad alanı özelliği olmadan). Bunu nasıl yapabilirim?


2
Bunun xml'nizi daha iyi gösterebileceğini düşündüğünüzü biliyorum, ancak ad alanları ve karşılık gelen xsd'ler sağlamak daha iyi bir uygulamadır.

2
Xml'mi yalnızca <message> olarak istiyorum, xmlns: xsi ve xmlns: xsd ad alanlarını atlamaktan bahsediyorum.
NetSide

5
Bilginize: Genel olarak bu aptalca bir hatadır. Ad alanları bir sebepten dolayı oradadır ve hepsini kaldırmak bir şeyleri bozacaktır. Seriyi kaldırma gibi şeyler.
John Saunders

66
Bazen bunun aptalca olmadığını ve bir hata olmadığını unutmayın. Örneğin, belge parçalarının oluşturulması ve daha sonra bir araya getirilmesi gerekebilir. Şahsen, çok sayıda benzer ve çok büyük belge oluşturmam gerekiyordu. Ağacın derinliklerinde hepsinde aynı büyük parçalar vardı. Bu yüzden, değişmez parçaları önceden oluşturmam ve belgeleri oluştururken bunları bayt dizileri olarak eklemem gerekiyordu. Bu yüzden çıktının daha okunaklı ve daha küçük olması için iç kısımlardaki bazı isim-alanı bildirimlerini atlamam gerekiyordu çünkü bunlar daha yüksek seviyelerde mevcuttu.
Dmitry Tashkinov

Yanıtlar:


233
...
XmlSerializer s = new XmlSerializer(objectToSerialize.GetType());
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("","");
s.Serialize(xmlWriter, objectToSerialize, ns);

2
Varsayılan ad alanını kaldırmanın istenmeyen sonuçlara yol açabileceğini eklemek isterim: örneğin, türetilmiş türleri serileştirmek için XmlInclude özniteliğini kullanırsanız, ad alanları bu öğelerin her birine eklenecektir, isteseniz de istemeseniz de, çünkü bunlar seriyi
kaldırma

3
Ayrıca, soru sorulduğu gibi bu, tüm xml ad alanlarını kaldırmaz . Soru belirtildiği gibi, sadece xsi ve xsd ad alanlarını kaldırır stackoverflow.com/questions/258960 da atıf yapıldığında, bu soruya.
Cheeso

1
Ayrıca kendi cevabımda belirtildiği gibi MS tarafından desteklenmiyor. Her zaman senin tipin başkalarıyla kullanılabilir, özellikle çalışmaz do ad alanlarını var.
fourpastmidnight

@ThomasLevesque, XmlInclude özniteliğini kullanırken varsayılan ad alanı nasıl kaldırılır?
Jeson Martajaya

4
Kısaltılabilirs.Serialize(writer, objectToSerialize, new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }));
Xeevis

27

Bu, iki cevabın 2.si.

Serileştirme sırasında bir belgedeki tüm ad alanlarını keyfi olarak çıkarmak istiyorsanız, bunu kendi XmlWriter'ınızı uygulayarak yapabilirsiniz.

En kolay yol, XmlTextWriter'dan türetmek ve ad alanları yayan StartElement yöntemini geçersiz kılmaktır. StartElement yöntemi, kök dahil herhangi bir öğe yayarken XmlSerializer tarafından çağrılır. Her öğe için ad alanını geçersiz kılarak ve onu boş dizeyle değiştirerek, ad alanlarını çıktıdan çıkardınız.

public class NoNamespaceXmlWriter : XmlTextWriter
{
    //Provide as many contructors as you need
    public NoNamespaceXmlWriter(System.IO.TextWriter output)
        : base(output) { Formatting= System.Xml.Formatting.Indented;}

    public override void WriteStartDocument () { }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        base.WriteStartElement("", localName, "");
    }
}

Bunun tür olduğunu varsayalım:

// explicitly specify a namespace for this type,
// to be used during XML serialization.
[XmlRoot(Namespace="urn:Abracadabra")]
public class MyTypeWithNamespaces
{
    // private fields backing the properties
    private int _Epoch;
    private string _Label;

    // explicitly define a distinct namespace for this element
    [XmlElement(Namespace="urn:Whoohoo")]
    public string Label
    {
        set {  _Label= value; } 
        get { return _Label; } 
    }

    // this property will be implicitly serialized to XML using the
    // member name for the element name, and inheriting the namespace from
    // the type.
    public int Epoch
    {
        set {  _Epoch= value; } 
        get { return _Epoch; } 
    }
}

Serileştirme sırasında böyle bir şeyi şu şekilde kullanırsınız:

        var o2= new MyTypeWithNamespaces { ..intializers.. };
        var builder = new System.Text.StringBuilder();
        using ( XmlWriter writer = new NoNamespaceXmlWriter(new System.IO.StringWriter(builder)))
        {
            s2.Serialize(writer, o2, ns2);
        }            
        Console.WriteLine("{0}",builder.ToString());

Yine de XmlTextWriter bir çeşit bozuk. Göre referans doc buna aşağıdakilerden kontrol etmez yazıyor:

  • Öznitelik ve öğe adlarında geçersiz karakterler.

  • Belirtilen kodlamaya uymayan Unicode karakterler. Unicode karakterleri belirtilen kodlamaya uymuyorsa, XmlTextWriter Unicode karakterlerinin karakter varlıklarına kaçışını yapmaz.

  • Yinelenen özellikler.

  • DOCTYPE genel tanımlayıcısındaki veya sistem tanımlayıcısındaki karakterler.

XmlTextWriter ile ilgili bu sorunlar .NET Framework v1.1'den beri var ve geriye dönük uyumluluk için kalacaklar. Bu sorunlar hakkında endişeleriniz yoksa, XmlTextWriter'ı kesinlikle kullanın. Ancak çoğu insan biraz daha fazla güvenilirlik ister.

Bunu elde etmek için, serileştirme sırasında ad alanlarını hala bastırırken, XmlTextWriter'dan türetmek yerine, soyut XmlWriter ve 24 yöntemlerinin somut bir uygulamasını tanımlayın .

Burada bir örnek var:

public class XmlWriterWrapper : XmlWriter
{
    protected XmlWriter writer;

    public XmlWriterWrapper(XmlWriter baseWriter)
    {
        this.Writer = baseWriter;
    }

    public override void Close()
    {
        this.writer.Close();
    }

    protected override void Dispose(bool disposing)
    {
        ((IDisposable) this.writer).Dispose();
    }

    public override void Flush()
    {
        this.writer.Flush();
    }

    public override string LookupPrefix(string ns)
    {
        return this.writer.LookupPrefix(ns);
    }

    public override void WriteBase64(byte[] buffer, int index, int count)
    {
        this.writer.WriteBase64(buffer, index, count);
    }

    public override void WriteCData(string text)
    {
        this.writer.WriteCData(text);
    }

    public override void WriteCharEntity(char ch)
    {
        this.writer.WriteCharEntity(ch);
    }

    public override void WriteChars(char[] buffer, int index, int count)
    {
        this.writer.WriteChars(buffer, index, count);
    }

    public override void WriteComment(string text)
    {
        this.writer.WriteComment(text);
    }

    public override void WriteDocType(string name, string pubid, string sysid, string subset)
    {
        this.writer.WriteDocType(name, pubid, sysid, subset);
    }

    public override void WriteEndAttribute()
    {
        this.writer.WriteEndAttribute();
    }

    public override void WriteEndDocument()
    {
        this.writer.WriteEndDocument();
    }

    public override void WriteEndElement()
    {
        this.writer.WriteEndElement();
    }

    public override void WriteEntityRef(string name)
    {
        this.writer.WriteEntityRef(name);
    }

    public override void WriteFullEndElement()
    {
        this.writer.WriteFullEndElement();
    }

    public override void WriteProcessingInstruction(string name, string text)
    {
        this.writer.WriteProcessingInstruction(name, text);
    }

    public override void WriteRaw(string data)
    {
        this.writer.WriteRaw(data);
    }

    public override void WriteRaw(char[] buffer, int index, int count)
    {
        this.writer.WriteRaw(buffer, index, count);
    }

    public override void WriteStartAttribute(string prefix, string localName, string ns)
    {
        this.writer.WriteStartAttribute(prefix, localName, ns);
    }

    public override void WriteStartDocument()
    {
        this.writer.WriteStartDocument();
    }

    public override void WriteStartDocument(bool standalone)
    {
        this.writer.WriteStartDocument(standalone);
    }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        this.writer.WriteStartElement(prefix, localName, ns);
    }

    public override void WriteString(string text)
    {
        this.writer.WriteString(text);
    }

    public override void WriteSurrogateCharEntity(char lowChar, char highChar)
    {
        this.writer.WriteSurrogateCharEntity(lowChar, highChar);
    }

    public override void WriteValue(bool value)
    {
        this.writer.WriteValue(value);
    }

    public override void WriteValue(DateTime value)
    {
        this.writer.WriteValue(value);
    }

    public override void WriteValue(decimal value)
    {
        this.writer.WriteValue(value);
    }

    public override void WriteValue(double value)
    {
        this.writer.WriteValue(value);
    }

    public override void WriteValue(int value)
    {
        this.writer.WriteValue(value);
    }

    public override void WriteValue(long value)
    {
        this.writer.WriteValue(value);
    }

    public override void WriteValue(object value)
    {
        this.writer.WriteValue(value);
    }

    public override void WriteValue(float value)
    {
        this.writer.WriteValue(value);
    }

    public override void WriteValue(string value)
    {
        this.writer.WriteValue(value);
    }

    public override void WriteWhitespace(string ws)
    {
        this.writer.WriteWhitespace(ws);
    }


    public override XmlWriterSettings Settings
    {
        get
        {
            return this.writer.Settings;
        }
    }

    protected XmlWriter Writer
    {
        get
        {
            return this.writer;
        }
        set
        {
            this.writer = value;
        }
    }

    public override System.Xml.WriteState WriteState
    {
        get
        {
            return this.writer.WriteState;
        }
    }

    public override string XmlLang
    {
        get
        {
            return this.writer.XmlLang;
        }
    }

    public override System.Xml.XmlSpace XmlSpace
    {
        get
        {
            return this.writer.XmlSpace;
        }
    }        
}

Ardından, daha önce olduğu gibi StartElement yöntemini geçersiz kılan türetilmiş bir sınıf sağlayın:

public class NamespaceSupressingXmlWriter : XmlWriterWrapper
{
    //Provide as many contructors as you need
    public NamespaceSupressingXmlWriter(System.IO.TextWriter output)
        : base(XmlWriter.Create(output)) { }

    public NamespaceSupressingXmlWriter(XmlWriter output)
        : base(XmlWriter.Create(output)) { }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        base.WriteStartElement("", localName, "");
    }
}

Ve sonra bu yazarı şu şekilde kullanın:

        var o2= new MyTypeWithNamespaces { ..intializers.. };
        var builder = new System.Text.StringBuilder();
        var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };
        using ( XmlWriter innerWriter = XmlWriter.Create(builder, settings))
            using ( XmlWriter writer = new NamespaceSupressingXmlWriter(innerWriter))
            {
                s2.Serialize(writer, o2, ns2);
            }            
        Console.WriteLine("{0}",builder.ToString());

Bunun için Oleg Tkachenko'ya kredi .


3
LookupPrefix(string ns)Tüm şema bildirimlerini kaldırmak için her zaman boş bir dize döndürmek için geçersiz kılmam gerektiğini de buldum .
Kevin Brock

Bu teknik olarak soruyu yanıtlamaz - XmlWriter değil, XmlTextWriter kullanıyorsunuz. Bununla birlikte kullanabileceğim XmlWriterSettings için XmlWriter kullanmak istediğim için fark ettim.
Abacus

@Abacus kodu okudun mu? O kullanır XmlWriter ve XmlWriterSettings .
Cheeso

benim hatam, bunu kaçırmış olmalıyım.
Abaküs

Harika Cevap, @KevinBrock'tan eklenen yönteme ek olarak, kodumun tüm ad alanlarının. Ayrıca ad alanı öneklerimin b2p1'den p2'ye değiştiğini de belirtmek gerekir ki bu da beni önekleri kullanan diğer yöntemleri kontrol etmeye yöneltti.
Mabdullah

15

Microsoft'un belgelerini ve çeşitli çözümlerini çevrimiçi olarak okuduktan sonra, bu sorunun çözümünü keşfettim. Hem yerleşik hem de XmlSerializerözel XML serileştirme ile çalışır IXmlSerialiazble.

MyTypeWithNamespacesŞimdiye kadar bu sorunun yanıtlarında kullanılan XML örneğinin aynısını kullanacağım .

[XmlRoot("MyTypeWithNamespaces", Namespace="urn:Abracadabra", IsNullable=false)]
public class MyTypeWithNamespaces
{
    // As noted below, per Microsoft's documentation, if the class exposes a public
    // member of type XmlSerializerNamespaces decorated with the 
    // XmlNamespacesDeclarationAttribute, then the XmlSerializer will utilize those
    // namespaces during serialization.
    public MyTypeWithNamespaces( )
    {
        this._namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] {
            // Don't do this!! Microsoft's documentation explicitly says it's not supported.
            // It doesn't throw any exceptions, but in my testing, it didn't always work.

            // new XmlQualifiedName(string.Empty, string.Empty),  // And don't do this:
            // new XmlQualifiedName("", "")

            // DO THIS:
            new XmlQualifiedName(string.Empty, "urn:Abracadabra") // Default Namespace
            // Add any other namespaces, with prefixes, here.
        });
    }

    // If you have other constructors, make sure to call the default constructor.
    public MyTypeWithNamespaces(string label, int epoch) : this( )
    {
        this._label = label;
        this._epoch = epoch;
    }

    // An element with a declared namespace different than the namespace
    // of the enclosing type.
    [XmlElement(Namespace="urn:Whoohoo")]
    public string Label
    {
        get { return this._label; }
        set { this._label = value; }
    }
    private string _label;

    // An element whose tag will be the same name as the property name.
    // Also, this element will inherit the namespace of the enclosing type.
    public int Epoch
    {
        get { return this._epoch; }
        set { this._epoch = value; }
    }
    private int _epoch;

    // Per Microsoft's documentation, you can add some public member that
    // returns a XmlSerializerNamespaces object. They use a public field,
    // but that's sloppy. So I'll use a private backed-field with a public
    // getter property. Also, per the documentation, for this to work with
    // the XmlSerializer, decorate it with the XmlNamespaceDeclarations
    // attribute.
    [XmlNamespaceDeclarations]
    public XmlSerializerNamespaces Namespaces
    {
        get { return this._namespaces; }
    }
    private XmlSerializerNamespaces _namespaces;
}

Hepsi bu sınıf için. Şimdi, bazıları XmlSerializerNamespacessınıflarının bir yerinde bir nesneye sahip olmaya itiraz etti ; ancak görebileceğiniz gibi, onu varsayılan kurucuda özenle sakladım ve ad alanlarını döndürmek için bir genel özelliği açığa çıkardım.

Şimdi, sınıfı serileştirme zamanı geldiğinde, aşağıdaki kodu kullanırsınız:

MyTypeWithNamespaces myType = new MyTypeWithNamespaces("myLabel", 42);

/******
   OK, I just figured I could do this to make the code shorter, so I commented out the
   below and replaced it with what follows:

// You have to use this constructor in order for the root element to have the right namespaces.
// If you need to do custom serialization of inner objects, you can use a shortened constructor.
XmlSerializer xs = new XmlSerializer(typeof(MyTypeWithNamespaces), new XmlAttributeOverrides(),
    new Type[]{}, new XmlRootAttribute("MyTypeWithNamespaces"), "urn:Abracadabra");

******/
XmlSerializer xs = new XmlSerializer(typeof(MyTypeWithNamespaces),
    new XmlRootAttribute("MyTypeWithNamespaces") { Namespace="urn:Abracadabra" });

// I'll use a MemoryStream as my backing store.
MemoryStream ms = new MemoryStream();

// This is extra! If you want to change the settings for the XmlSerializer, you have to create
// a separate XmlWriterSettings object and use the XmlTextWriter.Create(...) factory method.
// So, in this case, I want to omit the XML declaration.
XmlWriterSettings xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Encoding = Encoding.UTF8; // This is probably the default
// You could use the XmlWriterSetting to set indenting and new line options, but the
// XmlTextWriter class has a much easier method to accomplish that.

// The factory method returns a XmlWriter, not a XmlTextWriter, so cast it.
XmlTextWriter xtw = (XmlTextWriter)XmlTextWriter.Create(ms, xws);
// Then we can set our indenting options (this is, of course, optional).
xtw.Formatting = Formatting.Indented;

// Now serialize our object.
xs.Serialize(xtw, myType, myType.Namespaces);

Bunu yaptıktan sonra aşağıdaki çıktıyı almalısınız:

<MyTypeWithNamespaces>
    <Label xmlns="urn:Whoohoo">myLabel</Label>
    <Epoch>42</Epoch>
</MyTypeWithNamespaces>

Bu yöntemi, web servis çağrıları için XML'e serileştirilmiş derin bir sınıf hiyerarşisiyle yeni bir projede başarıyla kullandım. Microsoft'un belgeleri, bir XmlSerializerNamespaceskez oluşturduktan sonra herkes tarafından erişilebilen üye ile ne yapılacağı konusunda çok net değil ve pek çoğu bunun faydasız olduğunu düşünüyor. Ancak belgelerini izleyerek ve yukarıda gösterilen şekilde kullanarak, XmlSerializer'ın desteklenmeyen davranışa başvurmadan veya uygulayarak "kendi serileştirmenizi yuvarlayarak" sınıflarınız için XML üretme şeklini özelleştirebilirsiniz IXmlSerializable.

Umarım bu yanıt, .tarafından oluşturulan standartlardan xsive xsdad alanlarından nasıl kurtulacağımızı bir kez ve sonsuza kadar dinlendirir XmlSerializer.

GÜNCELLEME: OP'nin tüm ad alanlarını kaldırmayla ilgili sorusunu yanıtladığımdan emin olmak istiyorum. Yukarıdaki kodum bunun için çalışacak; size nasıl olduğunu göstereyim. Şimdi, yukarıdaki örnekte, gerçekten tüm ad alanlarından kurtulamazsınız (çünkü kullanımda iki ad alanı vardır). XML belgenizin bir yerinde, buna benzer bir şeye ihtiyacınız olacak xmlns="urn:Abracadabra" xmlns:w="urn:Whoohoo. Örnekteki sınıf daha büyük bir belgenin parçasıysa, o zaman bir ad alanının üzerinde bir yerde, biri (veya her ikisi için) Abracadbrave Whoohoo. Değilse, ad alanlarının biri veya her ikisindeki öğe bir tür önekle dekore edilmelidir (iki varsayılan ad alanınız olamaz, değil mi?). Öyleyse, bu örnek Abracadabraiçin defalt ad alanıdır. MyTypeWithNamespacesSınıfımın içine ad alanı için şu şekilde bir ad alanı öneki ekleyebilirim Whoohoo:

public MyTypeWithNamespaces
{
    this._namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] {
        new XmlQualifiedName(string.Empty, "urn:Abracadabra"), // Default Namespace
        new XmlQualifiedName("w", "urn:Whoohoo")
    });
}

Şimdi, sınıf tanımımda, <Label/>öğenin ad alanında olduğunu belirttim "urn:Whoohoo", bu nedenle daha fazla bir şey yapmam gerekmiyor. Şimdi yukarıdaki serileştirme kodumu değiştirmeden kullanarak sınıfı serileştirdiğimde, bu çıktı:

<MyTypeWithNamespaces xmlns:w="urn:Whoohoo">
    <w:Label>myLabel</w:Label>
    <Epoch>42</Epoch>
</MyTypeWithNamespaces>

Çünkü <Label>belgenin geri kalanından farklı bir ad alanında, bu, someway, bir ad ile "dekore" olmalıdır. Hiçbir hala var olduğunu Bildirimi xsive xsdad.


"Microsoft'un belgeleri açıkça desteklenmediğini söylüyor." Nerede paylaşmak ister misin?
Dave Van den Eynde


1
Hala ad alanlarını Serialize yöntemine geçiriyorsunuz. Herkese açık bir üye sağlama fikrinin, bunu yapmak zorunda olmayacağın olduğunu düşündüm. Yine de Serialize yöntemine geçirmeden çalışmasını sağlayamıyorum. Ve ne yazık ki, bu yöntem çağrısına erişimim yok. Yalnızca kullanılacak XmlSerializer örneğini ayarlayabilirim.
ezmek

Aslında xsi ve xsd ad alanlarını ne olursa olsun çıktıma zorlayan şeyin XmlWriteriçinde bulunduğunu XmlMediaTypeFormatterbuldum. Bu yalnızca WebApi'nin varsayılanını kullananları etkiler XmlMediaTypeFormatter. Bunun için kaynak kodunu kopyaladım XmlWriterve iki varsayılanı otomatik olarak eklemesini önlemek için gerektiği şekilde Namespaces özelliğimi Serialize yöntemine geçirmek için değiştirdim . Bkz bu cevabı
ezmek

@crush, bağlantı verdiğiniz yanıt yanıltıcı - yanlış değil, ancak iddialarının hepsi doğru değil. Cevabımdaki ilk kod parçacığına bakarsanız, XmlSerializer'ın. İle XmlSerializerNamespacesdekore edilmiş türdeki genel bir üyeyi ifşa ettiğinizde nasıl çalıştığını açıkça belirten bir yorum göreceksiniz XmlNamespacesDeclarationAttribute. Bu, doğrudan MSDN'den alınmıştır ve esasen XmlSerializer,.
fourpastmidnight

6

Bu soruya verdiğim iki cevabın ilkidir.

Ad alanları üzerinde tam kontrol istiyorsanız - örneğin bazılarını atlamak ama diğerlerini atlamak istemiyorsanız veya bir ad alanını diğeriyle değiştirmek istiyorsanız, bunu XmlAttributeOverrides kullanarak yapabilirsiniz .

Bu tür tanımına sahip olduğunuzu varsayalım:

// explicitly specify a namespace for this type,
// to be used during XML serialization.
[XmlRoot(Namespace="urn:Abracadabra")]
public class MyTypeWithNamespaces
{
    // private fields backing the properties
    private int _Epoch;
    private string _Label;

    // explicitly define a distinct namespace for this element
    [XmlElement(Namespace="urn:Whoohoo")]
    public string Label
    {
        set {  _Label= value; } 
        get { return _Label; } 
    }

    // this property will be implicitly serialized to XML using the
    // member name for the element name, and inheriting the namespace from
    // the type.
    public int Epoch
    {
        set {  _Epoch= value; } 
        get { return _Epoch; } 
    }
}

Ve bu serileştirme sözde kodu:

        var o2= new MyTypeWithNamespaces() { ..initializers...};
        ns.Add( "", "urn:Abracadabra" );
        XmlSerializer s2 = new XmlSerializer(typeof(MyTypeWithNamespaces));
        s2.Serialize(System.Console.Out, o2, ns);

Şu XML gibi bir şey elde edersiniz:

<MyTypeWithNamespaces xmlns="urn:Abracadabra">
  <Label xmlns="urn:Whoohoo">Cimsswybclaeqjh</Label>
  <Epoch>97</Epoch>
</MyTypeWithNamespaces>

Kök öğede varsayılan bir ad alanı ve "Etiket" öğesinde de ayrı bir ad alanı olduğuna dikkat edin. Bu ad alanları, yukarıdaki kodda türü süsleyen nitelikler tarafından dikte edildi.

.NET'teki Xml Serileştirme çerçevesi , gerçek kodu süsleyen öznitelikleri açıkça geçersiz kılma olasılığını içerir . Bunu XmlAttributesOverrides sınıfı ve arkadaşları ile yaparsınız. Diyelim ki aynı türe sahip olduğumu ve bunu şu şekilde serileştiriyorum:

        // instantiate the container for all attribute overrides
        XmlAttributeOverrides xOver = new XmlAttributeOverrides();

        // define a set of XML attributes to apply to the root element
        XmlAttributes xAttrs1 = new XmlAttributes();

        // define an XmlRoot element (as if [XmlRoot] had decorated the type)
        // The namespace in the attribute override is the empty string. 
        XmlRootAttribute xRoot = new XmlRootAttribute() { Namespace = ""};

        // add that XmlRoot element to the container of attributes
        xAttrs1.XmlRoot= xRoot;

        // add that bunch of attributes to the container holding all overrides
        xOver.Add(typeof(MyTypeWithNamespaces), xAttrs1);

        // create another set of XML Attributes
        XmlAttributes xAttrs2 = new XmlAttributes();

        // define an XmlElement attribute, for a type of "String", with no namespace
        var xElt = new XmlElementAttribute(typeof(String)) { Namespace = ""};

        // add that XmlElement attribute to the 2nd bunch of attributes
        xAttrs2.XmlElements.Add(xElt);

        // add that bunch of attributes to the container for the type, and
        // specifically apply that bunch to the "Label" property on the type.
        xOver.Add(typeof(MyTypeWithNamespaces), "Label", xAttrs2);

        // instantiate a serializer with the overrides 
        XmlSerializer s3 = new XmlSerializer(typeof(MyTypeWithNamespaces), xOver);

        // serialize
        s3.Serialize(System.Console.Out, o2, ns2);

Sonuç şuna benzer;

<MyTypeWithNamespaces>
  <Label>Cimsswybclaeqjh</Label>
  <Epoch>97</Epoch>
</MyTypeWithNamespaces>

Ad alanlarını kaldırdınız.

Mantıksal bir soru, serileştirme sırasında rasgele türlerden tüm ad alanlarını, açık geçersiz kılmalardan geçmeden çıkarabilir misiniz? Cevap EVET ve nasıl yapılacağı bir sonraki cevabımda.


6
XmlSerializer sr = new XmlSerializer(objectToSerialize.GetType());
TextWriter xmlWriter = new StreamWriter(filename);
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty, string.Empty);
sr.Serialize(xmlWriter, objectToSerialize, namespaces);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.