2012-03-01 84 views
2

我有一个字典类,它实现了具有自定义WriteXml和ReadXml实现的IXmlSerializable。 (下面的完整代码)当我使用的DataContractSerializer序列化,输出包含用于一般公知的类型,如int,长,串等的命名空间。如图所示:在使用DataContractSerializer序列化时删除已知类型的名称空间

<?xml version="1.0" encoding="utf-16"?> 
<MyDictionary> 
    <DictionaryItem Key="myInteger"> 
    <Value> 
     <int xmlns="http://schemas.microsoft.com/2003/10/Serialization/">4</int> 
    </Value> 
    </DictionaryItem> 
    <DictionaryItem Key="myLong"> 
    <Value> 
     <long xmlns="http://schemas.microsoft.com/2003/10/Serialization/">5</long> 
    </Value> 
    </DictionaryItem> 
    <DictionaryItem Key="myString"> 
    <Value> 
     <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">testing</string> 
    </Value> 
    </DictionaryItem> 
</MyDictionary> 

如何删除它,以便它看起来像下面?谢谢!

<?xml version="1.0" encoding="utf-16"?> 
<MyDictionary> 
    <DictionaryItem Key="myInteger"> 
    <Value> 
     <int>4</int> 
    </Value> 
    </DictionaryItem> 
    <DictionaryItem Key="myLong"> 
    <Value> 
     <long>5</long> 
    </Value> 
    </DictionaryItem> 
    <DictionaryItem Key="myString"> 
    <Value> 
     <string>testing</string> 
    </Value> 
    </DictionaryItem> 
</MyDictionary> 

我用来创建输出的测试代码:

private void button1_Click(object sender, EventArgs e) 
    { 
     MyDictionary myDictionary = new MyDictionary(); 
     myDictionary.Add("myInteger", 4); 
     Int64 myLong = 5; 
     myDictionary.Add("myLong", myLong); 
     myDictionary.Add("myString", "testing"); 

     string outputXml = GetXmlForObject(myDictionary); 
     System.IO.File.WriteAllText(@"C:\outputXml.txt", outputXml); 
    } 

    public static string GetXmlForObject(Object obj) 
    { 
     try 
     { 
      DataContractSerializer serializer = new DataContractSerializer(obj.GetType()); 
      StringBuilder builder = new StringBuilder(); 
      XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); 
      xmlWriterSettings.NamespaceHandling = NamespaceHandling.OmitDuplicates; 
      xmlWriterSettings.Indent = true; 
      using (XmlWriter writer = XmlWriter.Create(builder, xmlWriterSettings)) 
      { 
       serializer.WriteObject(writer, obj); 
      } 
      return builder.ToString(); 
     } 
     catch (Exception exception) 
     { 
      return String.Empty; 
     } 
    } 
下面

全码:

[XmlRoot(Namespace = "")] 
public class MyDictionary : Dictionary<String, Object>, IXmlSerializable, ISerializable 
{ 
    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     throw new NotImplementedException("The method is not implemented."); 
    } 

    public void ReadXml(System.Xml.XmlReader reader) 
    { 
     try 
     { 
      string key = null; 
      object value = null; 

      if (reader.IsStartElement() && !reader.IsEmptyElement) 
      { 
       reader.ReadStartElement(); 

       while (reader.NodeType != XmlNodeType.EndElement) 
       { 
        key = reader.GetAttribute("Key"); 
        string typeAttribute = reader.GetAttribute("Null"); 
        reader.ReadStartElement("DictionaryItem"); 
        if (reader.IsEmptyElement) 
        { 
         this.Add(key, null); 
         reader.ReadStartElement(); 
        } 
        else 
        { 
         reader.ReadStartElement("Value"); 
         value = GetValueDeserializer(reader.LocalName).ReadObject(reader.ReadSubtree()); 
         this.Add(key, value); 
         reader.Skip(); // skipping in case the string is empty or null 
         reader.ReadEndElement(); // Reading end node for Value 
        } 

        reader.ReadEndElement(); // Reading end node for element in the list 
       } 

       reader.ReadEndElement(); 
      } 
     } 

     catch (XmlException e) 
     { 
      throw new XmlException("ReadXml(XmlReader) reader pointing to invalid element", e); 
     } 
    } 

    private DataContractSerializer GetValueDeserializer(string typeStr) 
    { 
     Type valueType = GetTypeFromStratusType(typeStr); 
     return new DataContractSerializer(valueType); 
    } 

    public static Type GetTypeFromStratusType(string typeStr) 
    { 
     Type valueType; 

     switch (typeStr) 
     { 
      case "short": 
       valueType = typeof(Int16); 
       break; 
      case "int": 
       valueType = typeof(Int32); 
       break; 
      case "long": 
       valueType = typeof(Int64); 
       break; 
      case "string": 
       valueType = typeof(String); 
       break; 
      default: 
       valueType = typeof(String); 
       break; 
     } 

     return valueType; 
    } 

    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
     foreach (KeyValuePair<String, Object> item in this) 
     { 
      writer.WriteStartElement("DictionaryItem"); 
      writer.WriteAttributeString("Key", item.Key.ToString()); 
      if (item.Value != null) 
      { 
       writer.WriteStartElement("Value"); 
       DataContractSerializer serializer = new DataContractSerializer(item.Value.GetType()); 
       serializer.WriteObject(writer, item.Value); 
      } 
      else 
      { 
       writer.WriteStartElement("Value"); 
      } 
      writer.WriteEndElement(); 
      writer.WriteEndElement(); 
     } 
    } 
} 

回答

2

您可以创建绕过写命名一个XmlTextWriter,并把它插入到你的序列化程序。默认。序列化程序使用一个文本编写器,它通过创建方法XmlDictionaryWriter.CreateTextWriter(...)来获得,它写出命名空间(这当然是您的问题!)

此自定义序列化程序不会写出命名空间,它应该解决你的问题。

public class CustomXmlTextWriter : XmlTextWriter 
{  
    public override void WriteStartElement(string prefix, string localName, string ns) 
    { 
    base.WriteStartElement(null, localName, ""); 
    } 
} 
相关问题