Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用字典将xml反序列化为对象_C#_Xml - Fatal编程技术网

C# 使用字典将xml反序列化为对象

C# 使用字典将xml反序列化为对象,c#,xml,C#,Xml,这是我的班级结构: class DataItem { public string Id { get; set; } public string Type { get; set; } private Dictionary<string, DataProperty> properties = new Dictionary<string, DataProperty>(); public Dictionary<string, DataProper

这是我的班级结构:

class DataItem
{
   public string Id { get; set; }
   public string Type { get; set; }

   private Dictionary<string, DataProperty> properties = new Dictionary<string, DataProperty>();

   public Dictionary<string, DataProperty> Properties
   {
       get { return properties; }
       set { properties = value; }
   }
}

public class DataProperty
{    
      public string Key { get; set; }
      public string Value { get; set; }
      public bool Required { get; set; }
}
类数据项
{
公共字符串Id{get;set;}
公共字符串类型{get;set;}
私有字典属性=新字典();
公共字典属性
{
获取{返回属性;}
设置{properties=value;}
}
}
公共类数据属性
{    
公共字符串密钥{get;set;}
公共字符串值{get;set;}
需要公共bool{get;set;}
}
这是我想要使用的XML(注意:如果需要,我可以更改XML):


ph15
核心
大小
50%
假的
颜色
红色
真的
ph234
核心
最终,应将XML加载到另一个字典中:

private Dictionary<string, DataItem> Mydata;
私有字典Mydata;

不幸的是,通用词典不可xml序列化。

解决方法是将一个单独的字段变大,专门用于支持将字典元素公开为键/值对列表的序列化。然后还必须使用
XmlIgnore
属性标记dictionary成员

或者,您也可以使用XmlSerializer(如)以外的支持字典类型的东西

下面是一个示例,它提供了一个很好的示例,说明如何修改您的类型以支持使用字典的XML序列化

如果使用此代码,一个重要的问题是:序列化项可能以任意顺序出现在输出中。这是使用字典(无序)作为数据存储模型的结果

[XmlIgnore()]   
public Dictionary<string, DataProperty> Properties
{   
    set { properties = value; }   
    get { return properties ; }   
}


[XmlArray("Stuff")]   
[XmlArrayItem("StuffLine", Type=typeof(DictionaryEntry))]   
public DictionaryEntry[] PropertiesList
{   
    get  
    {   
        //Make an array of DictionaryEntries to return   
        DictionaryEntry[] ret=new DictionaryEntry[Properties.Count];   
        int i=0;   
        DictionaryEntry de;   
        //Iterate through Stuff to load items into the array.   
        foreach (KeyValuePair<string, DataProperty> props in Properties)   
        {   
            de = new DictionaryEntry();   
            de.Key = props.Key;   
            de.Value = props.Value;   
            ret[i]=de;   
            i++;   
        }   
        return ret;   
    }   
    set  
    {   
        Properties.Clear();   
        for (int i=0; i<value.Length; i++)   
        {   
            Properties.Add((string)value[i].Key, (DataProperty)value[i].Value);   
        }   
    }   
}  
[XmlIgnore()]
公共字典属性
{   
设置{properties=value;}
获取{返回属性;}
}
[XmlArray(“Stuff”)]
[XmlArrayItem(“填充行”,Type=typeof(DictionaryEntry))]
公共字典entry[]属性列表
{   
得到
{   
//创建一个要返回的DictionaryEntry数组
DictionaryEntry[]ret=新DictionaryEntry[Properties.Count];
int i=0;
词典;
//遍历所有内容以将项加载到数组中。
foreach(属性中的KeyValuePair道具)
{   
de=新字典entry();
de.Key=道具.Key;
de.值=道具值;
ret[i]=de;
i++;
}   
返回ret;
}   
设置
{   
Properties.Clear();

对于(int i=0;i不幸的是,通用字典不能进行xml序列化。

解决方法是将一个单独的字段变大,专门用于支持将字典元素公开为键/值对列表的序列化。然后还必须使用
XmlIgnore
属性标记字典成员

或者,您也可以使用XmlSerializer(如)以外的支持字典类型的东西

下面是一个示例,它提供了一个很好的示例,说明如何修改您的类型以支持使用字典的XML序列化

如果使用此代码,一个重要的问题是:序列化项可能以任意顺序出现在输出中。这是使用字典(无序)作为数据存储模型的结果

[XmlIgnore()]   
public Dictionary<string, DataProperty> Properties
{   
    set { properties = value; }   
    get { return properties ; }   
}


[XmlArray("Stuff")]   
[XmlArrayItem("StuffLine", Type=typeof(DictionaryEntry))]   
public DictionaryEntry[] PropertiesList
{   
    get  
    {   
        //Make an array of DictionaryEntries to return   
        DictionaryEntry[] ret=new DictionaryEntry[Properties.Count];   
        int i=0;   
        DictionaryEntry de;   
        //Iterate through Stuff to load items into the array.   
        foreach (KeyValuePair<string, DataProperty> props in Properties)   
        {   
            de = new DictionaryEntry();   
            de.Key = props.Key;   
            de.Value = props.Value;   
            ret[i]=de;   
            i++;   
        }   
        return ret;   
    }   
    set  
    {   
        Properties.Clear();   
        for (int i=0; i<value.Length; i++)   
        {   
            Properties.Add((string)value[i].Key, (DataProperty)value[i].Value);   
        }   
    }   
}  
[XmlIgnore()]
公共字典属性
{   
设置{properties=value;}
获取{返回属性;}
}
[XmlArray(“Stuff”)]
[XmlArrayItem(“填充行”,Type=typeof(DictionaryEntry))]
公共字典entry[]属性列表
{   
得到
{   
//创建一个要返回的DictionaryEntry数组
DictionaryEntry[]ret=新DictionaryEntry[Properties.Count];
int i=0;
词典;
//遍历所有内容以将项加载到数组中。
foreach(属性中的KeyValuePair道具)
{   
de=新字典entry();
de.Key=道具.Key;
de.值=道具值;
ret[i]=de;
i++;
}   
返回ret;
}   
设置
{   
Properties.Clear();

对于(inti=0;i简短的回答:你不能

这是因为即使您可以想象序列化方案,.NET Serializer也不能保证重新序列化的密钥将具有相同的哈希值

长篇大论的回答:你可以,但这需要大量的工作

您的解决方案是对整个对象进行手动序列化,或者用一个简单的包装器属性替换Dictionary,该属性包装了
IDictionary
,但将其公开为对列表(如果需要,您可以稍后对其进行转换)


但是:这留下了与上述相同的问题,您无法保证重新序列化的密钥将具有与序列化前相同的哈希代码。

简短回答:您不能

这是因为即使您可以想象序列化方案,.NET Serializer也不能保证重新序列化的密钥将具有相同的哈希值

长篇大论的回答:你可以,但这需要大量的工作

您的解决方案是对整个对象进行手动序列化,或者用一个简单的包装器属性替换Dictionary,该属性包装了
IDictionary
,但将其公开为对列表(如果需要,您可以稍后对其进行转换)


然而:这留下了与上述相同的问题,您无法保证重新序列化的密钥将具有与序列化之前相同的哈希代码。

我建议您使用DataContractSerializer。它确实支持字典。

我建议您使用DataContractSerializer。它确实支持字典。

我知道这一点正如前面所回答的,但由于我有一种非常简洁的方法(代码)来使用DataContractSerializer类进行IDictionary序列化(由WCF使用,但可以和
public static class SerializationExtensions
{
    public static string Serialize<T>(this T obj)
    {
        var serializer = new DataContractSerializer(obj.GetType());
        using (var writer = new StringWriter())
        using (var stm = new XmlTextWriter(writer))
        {
            serializer.WriteObject(stm, obj);
            return writer.ToString();
        }
    }
    public static T Deserialize<T>(this string serialized)
    {
        var serializer = new DataContractSerializer(typeof(T));
        using (var reader = new StringReader(serialized))
        using (var stm = new XmlTextReader(reader))
        {
            return (T)serializer.ReadObject(stm);
        }
    }
}
// dictionary to serialize to string
Dictionary<string, object> myDict = new Dictionary<string, object>();
// add items to the dictionary...
myDict.Add(...);
// serialization is straight-forward
string serialized = myDict.Serialize();
...
// deserialization is just as simple
Dictionary<string, object> myDictCopy = 
    serialized.Deserialize<Dictionary<string,object>>();