我有一个字典类,它使用自定义WriteXml和ReadXml实现来实现IXmlSerializable。 (下面的完整代码)当我使用DataContractSerializer对其进行序列化时,输出包含一般已知类型的名称空间,如int,long,string等。如图所示:
<?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();
}
}
}
答案 0 :(得分:3)
您可以创建一个绕过编写命名空间的XmlTextWriter,并将其插入序列化程序。默认情况下。序列化程序使用文本编写器,它通过创建方法XmlDictionaryWriter.CreateTextWriter(...)来获取,它会写出命名空间(这当然是你的问题!)
这个自定义序列化程序根本不会写出命名空间,它应该可以解决你的问题。
public class CustomXmlTextWriter : XmlTextWriter
{
public override void WriteStartElement(string prefix, string localName, string ns)
{
base.WriteStartElement(null, localName, "");
}
}