在XML序列化过程中删除命名空间 [英] Remove Namespaces During XML Serialization
问题描述
给出以下通用序列化代码:
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屋!