在XML序列化期间删除命名空间

鉴于此通用序列化代码:

public virtual string Serialize(System.Text.Encoding encoding) { System.IO.StreamReader streamReader = null; System.IO.MemoryStream memoryStream = null; memoryStream = new System.IO.MemoryStream(); System.Xml.XmlWriterSettings xmlWriterSettings = new System.Xml.XmlWriterSettings(); xmlWriterSettings.Encoding = encoding; System.Xml.XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings); Serializer.Serialize(xmlWriter, this); memoryStream.Seek(0, System.IO.SeekOrigin.Begin); streamReader = new System.IO.StreamReader(memoryStream); return streamReader.ReadToEnd(); } 

和这个对象(来自xsd2code):

 [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.225")] [System.SerializableAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "Com.Foo.Request")] [System.Xml.Serialization.XmlRootAttribute(Namespace = "Com.Foo.Request", IsNullable = false)] public partial class REQUEST_GROUP { [EditorBrowsable(EditorBrowsableState.Never)] private List rEQUESTING_PARTYField; [EditorBrowsable(EditorBrowsableState.Never)] private RECEIVING_PARTY rECEIVING_PARTYField; [EditorBrowsable(EditorBrowsableState.Never)] private SUBMITTING_PARTY sUBMITTING_PARTYField; [EditorBrowsable(EditorBrowsableState.Never)] private REQUEST rEQUESTField; [EditorBrowsable(EditorBrowsableState.Never)] private string iDField; public REQUEST_GROUP() { this.rEQUESTField = new REQUEST(); this.sUBMITTING_PARTYField = new SUBMITTING_PARTY(); this.rECEIVING_PARTYField = new RECEIVING_PARTY(); this.rEQUESTING_PARTYField = new List(); this.IDField = "2.1"; } } 

使用utf-8编码从Serialize输出:

编辑问题1:如何以这种方式装饰类,或者在处理过程中操纵序列化程序去除REQUEST_GROUP节点中的所有名称空间,而不是使用xslt或regex进行后处理。

问题2:如果您也可以添加文档类型,则可以获得奖励积分。

谢谢。

如果您只想删除命名空间别名 ,那么如前所示,您可以使用XmlSerializerNamespaces强制XmlSerializer在每个元素上显式使用命名空间(即xmlns="blah" ),而不是声明别名并使用别名。

但是,无论您如何处理别名,该元素的基本名称都是Com.Foo.Request命名空间中的 REQUEST_GROUP 。 如果没有表示对底层数据的重大更改,则无法完全删除命名空间 – 即某个人某处将获得exception(由于获取它未预期的数据 – 特别是根命名空间中的REQUEST_GROUP )。 在C#术语中,它是System.StringMy.Custom.String之间的区别 – 当然,它们都被称为String ,但这只是它们的本地名称。

如果你删除命名空间的所有痕迹,那么一个实用的选项是编辑[XmlRoot(...)][XmlType(...)]Namespace=...条目(以及其他任何地方)未在示例中显示)。

如果类型不在您的控件之内,您也可以在运行时使用XmlAttributeOverrides执行此操作 – 但需要注意的是:如果使用XmlAttributeOverrides创建XmlSerializer ,则必须缓存并重新使用它 – 否则您的AppDomain将泄漏(它会在在此模式下每个序列化器飞行,并且无法卸载程序集)。

您可以删除这样的名称空间:

 XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add(string.Empty, string.Empty); ns.Add(string.Empty, "Com.Foo.Request"); Serializer.Serialize(xmlWriter, this, ns); 

至于添加doctype,我知道可以创建一个自定义的XmlWriter并使用一个调用WriteDocType的方法覆盖WriteStartDocument ,但我希望其他人知道比这更简单的方法。

编辑:顺便说一下,我强烈建议using

 using(System.Xml.XmlWriter xmlWriter = XmlWriter.Create(etc.)) { // use it here. } 

当块结束时,它通过调用Dispose方法自动处理流的整理。