To jest druga z dwóch odpowiedzi.
Jeśli chcesz po prostu usunąć wszystkie przestrzenie nazw z dokumentu podczas serializacji, możesz to zrobić, implementując własny XmlWriter.
Najłatwiejszym sposobem jest wyprowadzenie z XmlTextWriter i zastąpienie metody StartElement, która emituje przestrzenie nazw. Metoda StartElement jest wywoływana przez XmlSerializer podczas emitowania jakichkolwiek elementów, w tym katalogu głównego. Zastępując przestrzeń nazw dla każdego elementu i zastępując ją pustym ciągiem, usunęliśmy przestrzenie nazw z danych wyjściowych.
public class NoNamespaceXmlWriter : XmlTextWriter
{
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, "");
}
}
Załóżmy, że jest to typ:
[XmlRoot(Namespace="urn:Abracadabra")]
public class MyTypeWithNamespaces
{
private int _Epoch;
private string _Label;
[XmlElement(Namespace="urn:Whoohoo")]
public string Label
{
set { _Label= value; }
get { return _Label; }
}
public int Epoch
{
set { _Epoch= value; }
get { return _Epoch; }
}
}
Oto, jak możesz użyć takiej rzeczy podczas serializacji:
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());
XmlTextWriter jest jednak trochę uszkodzony. Zgodnie z dokumentem referencyjnym , kiedy pisze, nie sprawdza następujących elementów:
Nieprawidłowe znaki w nazwach atrybutów i elementów.
Znaki Unicode, które nie pasują do określonego kodowania. Jeśli znaki Unicode nie pasują do określonego kodowania, XmlTextWriter nie zmienia znaczenia znaków Unicode w jednostkach znakowych.
Zduplikowane atrybuty.
Znaki w publicznym identyfikatorze DOCTYPE lub identyfikatorze systemowym.
Te problemy z XmlTextWriter istniały od wersji 1.1 .NET Framework i pozostaną, ze względu na wsteczną kompatybilność. Jeśli nie masz obaw dotyczących tych problemów, zdecydowanie użyj XmlTextWriter. Ale większość ludzi chciałaby trochę większej niezawodności.
Aby to uzyskać, nadal pomijając przestrzenie nazw podczas serializacji, zamiast wyprowadzać z XmlTextWriter, zdefiniuj konkretną implementację abstrakcyjnego XmlWriter i jego 24 metod.
Oto przykład:
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;
}
}
}
Następnie podaj klasę pochodną, która zastępuje metodę StartElement, tak jak poprzednio:
public class NamespaceSupressingXmlWriter : XmlWriterWrapper
{
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, "");
}
}
A potem użyj tego pisarza w ten sposób:
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());
Kredyt za to Oleg Tkachenko .