이것은 두 가지 답변 중 두 번째입니다.
직렬화 중에 문서에서 모든 네임 스페이스를 임의로 제거하려는 경우 고유 한 XmlWriter를 구현하여이를 수행 할 수 있습니다.
가장 쉬운 방법은 XmlTextWriter에서 파생하여 네임 스페이스를 내보내는 StartElement 메서드를 재정의하는 것입니다. StartElement 메서드는 루트를 포함한 모든 요소를 방출 할 때 XmlSerializer에 의해 호출됩니다. 각 요소의 네임 스페이스를 재정의하고 빈 문자열로 바꾸면 출력에서 네임 스페이스를 제거했습니다.
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, "");
}
}
이것이 유형이라고 가정하십시오.
// 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; }
}
}
직렬화 중에 이러한 것을 사용하는 방법은 다음과 같습니다.
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는 다소 고장났습니다. 참조 doc 에 따르면 쓸 때 다음을 확인하지 않습니다.
속성 및 요소 이름에 유효하지 않은 문자가 있습니다.
지정된 인코딩에 맞지 않는 유니 코드 문자 유니 코드 문자가 지정된 인코딩에 맞지 않으면 XmlTextWriter는 유니 코드 문자를 문자 엔터티로 이스케이프하지 않습니다.
속성이 중복되었습니다.
DOCTYPE 공용 식별자 또는 시스템 식별자의 문자
XmlTextWriter에 대한 이러한 문제는 .NET Framework v1.1 이후로 발생했으며 이전 버전과의 호환성을 위해 계속 남아 있습니다. 이러한 문제에 대해 걱정이 없다면 반드시 XmlTextWriter를 사용하십시오. 그러나 대부분의 사람들은 조금 더 신뢰성을 원합니다.
그것을 얻으려면 XmlTextWriter에서 파생하는 대신 직렬화 중에 네임 스페이스를 계속 억제하면서 추상 XmlWriter 및 24 메소드 의 구체적인 구현을 정의하십시오 .
예를 들면 다음과 같습니다.
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;
}
}
}
그런 다음 이전과 같이 StartElement 메소드를 대체하는 파생 클래스를 제공하십시오.
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, "");
}
}
그런 다음이 작가를 다음과 같이 사용하십시오.
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());
Oleg Tkachenko 에게 이것에 대한 신용 .