我有一个非常奇怪的情况.我像这样序列化我的命名空间:
var namespaces = new XmlSerializerNamespaces(); namespaces.Add("xsd","http://www.w3.org/2001/XMLSchema"); namespaces.Add("xsi","http://www.w3.org/2001/XMLSchema-instance"); serializer.Serialize(writer,config,namespaces);
在我的机器上,我得到以下xml(一行我刚刚添加了换行符):
<SystemConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.schaeffler.com/sara/systemconfiguration/">
在构建服务器上,我使用相同的软件:
<SystemConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.schaeffler.com/sara/systemconfiguration/">
你看到xsd和xsi的顺序是交换的.我检查了序列化程序的实现,发现顺序是用散列表确定的,并且XmlSerializerNamespaces没有接口来为命名空间实现我自己的序列化程序.
这是XmlSerializationWriter中的方法:
protected void WriteNamespaceDeclarations(XmlSerializerNamespaces xmlns) { if (xmlns != null) { foreach (DictionaryEntry dictionaryEntry in xmlns.Namespaces) { string localName = (string) dictionaryEntry.Key; string ns = (string) dictionaryEntry.Value; if (this.namespaces != null) { string str = this.namespaces.Namespaces[(object) localName] as string; if (str != null && str != ns) throw new InvalidOperationException(Res.GetString("XmlDuplicateNs",(object) localName,(object) ns)); } string str1 = ns == null || ns.Length == 0 ? (string) null : this.Writer.LookupPrefix(ns); if (str1 == null || str1 != localName) this.WriteAttribute("xmlns",localName,(string) null,ns); } } this.namespaces = (XmlSerializerNamespaces) null; }
什么可以导致hashmap中命名空间的不同顺序?
解决方法
来自msdn:
The elements are sorted according to the hash value of the key,and
each key can exist only once in the collection.
DictionaryEntry(结构)的哈希值是从ValueType.GetHashCode()中提取的.它可能返回一个不可确定的密钥 – 可能基于潜在的参考值.您需要进行一些进一步的反思,以确定如何计算哈希值.它可能只是使用默认对象实现.
也来自msdn:
A hash code is intended for efficient insertion and lookup in collections that are based on a hash table. A hash code is not a permanent value.