在XML序列化过程中删除命名空间 [英] Remove Namespaces During XML Serialization

查看:69
本文介绍了在XML序列化过程中删除命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下通用序列化代码:

Given this generic serialization code:

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生成):

and this object (gen'd from 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_PARTY> 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<REQUESTING_PARTY>();
  this.IDField = "2.1";
 }
}

序列化为utf-8的输出:

Output from the Serialize with an encode of utf-8:

<?xml version ="1.0" encoding ="utf-8"?>< REQUEST_GROUP xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd ="http://www.w3.org/2001/XMLSchema" ID ="2.1" xmlns ="Com.Foo.Request">< RECEIVING_PARTY/>< SUBMITTING_PARTY/>< REQUEST LoginAccountIdentifier ="xxx" LoginAccountPassword ="yyy" _RecordIdentifier =" _JobIdentifier =">< REQUESTDATA>< PROPERTY_INFORMATION_REQUEST _SpecialInstructionsDescription =" _ActionType ="Submit">< _DATA_PRODUCT _ShortSubjectReport ="Y"/>< _PROPERTY_CRITERIA _City =阳光城" _StreetAddress2 =" _StreetAddress ="123 Main Street" _State ="CA" _PostalCode ="12345">< PARSED_STREET_ADDRESS/></_ PROPERTY_CRITERIA>< _SEARCH_CRITERIA/>< _RESPONSE_CRITERIA/></PROPERTY_INFORMATION_REQUEST></REQUESTDATA></REQUEST></REQUEST_GROUP>

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

EDIT Question 1: How do I decorate the class in such a fashion, or manipulate the serializer to get rid of all the namespaces in the REQUEST_GROUP node during processing, NOT post-processing with xslt or regex.

问题2:如果您还可以添加文档类型,则可以加分.

Question 2: Bonus point if you could add the doc type too.

谢谢.

推荐答案

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

If you just want to remove the namespace aliases, then as already shown you can use XmlSerializerNamespaces to force XmlSerializer to use the namespace explicitly (i.e. xmlns="blah") on each element, rather than declaring an alias and using the alias instead.

但是,无论您使用别名做什么,该元素的基本名称都是 Com.Foo.Request 名称空间中的 REQUEST_GROUP .您不能完全删除名称空间 ,除非该名称空间表示对基础数据的重大更改-即某个地方的某人将要获取异常(由于获取了意外的数据-特别是根名称空间中的REQUEST_GROUP ).用C#术语来说,这是 System.String My.Custom.String 之间的区别-当然,它们都被称为 String ,但是只是他们的 local 名称.

However, regardless of what you do with the aliases, the fundamental name of that element is REQUEST_GROUP in the Com.Foo.Request namespace. You can't remove the namespace completely without that representing a breaking change to the underlying data - i.e. somebody somewhere is going to get an exception (due to getting data it didn't expect - specifically REQUEST_GROUP in the root namespace). In C# terms, it is the difference between System.String and My.Custom.String - sure, they are both called String, but that is just their local name.

如果您想要要删除名称空间的所有痕迹,那么务实的选择是从 [XmlRoot]中删除 Namespace = ... 条目(...)] [XmlType(...)] (以及示例中未显示的其他任何地方).

If you want to remove all traces of the namespace, then a pragmatic option would be to edit away the Namespace=... entries from [XmlRoot(...)] and [XmlType(...)] (plus anywhere else that isn't shown in the example).

如果类型不在您的控制范围内,则还可以在运行时使用 XmlAttributeOverrides 进行操作-但要注意:如果使用 XmlAttributeOverrides创建 XmlSerializer 必须 缓存并重新使用它-否则您的 AppDomain 会泄漏(它会动态地 per序列化器(在这种模式下,程序集不能卸载).

If the types are outside of your control, you can also do this at runtime using XmlAttributeOverrides - but a caveat: if you create an XmlSerializer using XmlAttributeOverrides you must cache and re-use it - otherwise your AppDomain will leak (it creates assemblies on the fly per serializer in this mode, and assemblies cannot be unloaded).

这篇关于在XML序列化过程中删除命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆