Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.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_Xml Serialization_Xmlserializer - Fatal编程技术网

C# 反序列化具有唯一属性的重复XML元素

C# 反序列化具有唯一属性的重复XML元素,c#,xml,xml-serialization,xmlserializer,C#,Xml,Xml Serialization,Xmlserializer,我有以下XML结构: <Response> <Value Name="ID">1</Value> <Value Name="User">JSmith</Value> <Value Name="Description">Testing 123</Value> </Response> 该XML被构造为名称/值对的集合,而不是具有预定义属性的类,因此反序列化它将更容易、更自然 如果您决定反序列

我有以下XML结构:

<Response>
  <Value Name="ID">1</Value>
  <Value Name="User">JSmith</Value>
  <Value Name="Description">Testing 123</Value>
</Response>

该XML被构造为名称/值对的集合,而不是具有预定义属性的类,因此反序列化它将更容易、更自然

如果您决定反序列化到一个类中,假设您正在使用,您可以为此目的引入一个名称/值对的代理数组,如下所示:

public class NameValuePair
{
    [XmlAttribute]
    public string Name { get; set; }

    [XmlText]
    public string Value { get; set; }

    public override string ToString()
    {
        return string.Format("Name={0}, Value=\"{1}\"", Name, Value);
    }
}

[Serializable]
[XmlRoot("Response")]
public class ReportingResponse
{
    [XmlElement(ElementName="Value")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public NameValuePair[] XmlNameValuePairs
    {
        get
        {
            return NameValuePairExtensions.GetNamedValues(this).ToArray();
        }
        set
        {
            NameValuePairExtensions.SetNamedValues(this, value);
        }
    }

    [XmlIgnore]
    public string ID { get; set; }

    [XmlIgnore]
    public string User { get; set; }

    [XmlIgnore]
    public string Description { get; set; }
}
然后进行一些反射以自动加载阵列:

public static class NameValuePairExtensions
{
    public static List<NameValuePair> GetNamedValues<T>(T obj)
    {
        if (obj == null)
            throw new ArgumentNullException();
        var type = obj.GetType();
        var properties = type.GetProperties();
        List<NameValuePair> list = new List<NameValuePair>();
        foreach (var prop in properties)
        {
            if (prop.PropertyType == typeof(string))
            {
                var getter = prop.GetGetMethod();
                var setter = prop.GetSetMethod();

                if (getter != null && setter != null) // Confirm this property has public getters & setters.
                {
                    list.Add(new NameValuePair() { Name = prop.Name, Value = (string)getter.Invoke(obj, null) });
                }
            }
        }
        return list;
    }

    public static void SetNamedValues<T>(T obj, IEnumerable<NameValuePair> values)
    {
        if (obj == null || values == null)
            throw new ArgumentNullException();
        var type = obj.GetType();
        foreach (var value in values)
        {
            var prop = type.GetProperty(value.Name);
            if (prop == null)
            {
                Debug.WriteLine(string.Format("No public property found for {0}", value));
                continue;
            }
            try
            {
                prop.SetValue(obj, value.Value, null);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception setting " + value.ToString() + " : \n" + ex.ToString());
            }
        }
    }
}
公共静态类nameValuePairex
{
公共静态列表GetNamedValues(T obj)
{
if(obj==null)
抛出新ArgumentNullException();
var type=obj.GetType();
var properties=type.GetProperties();
列表=新列表();
foreach(属性中的var属性)
{
if(prop.PropertyType==typeof(string))
{
var getter=prop.getMethod();
var setter=prop.GetSetMethod();
if(getter!=null&&setter!=null)//确认此属性具有公共getter&setter。
{
Add(newnamevaluepair(){Name=prop.Name,Value=(string)getter.Invoke(obj,null)});
}
}
}
退货清单;
}
公共静态void setNamedValue(T对象,IEnumerable值)
{
if(obj==null | | values==null)
抛出新ArgumentNullException();
var type=obj.GetType();
foreach(值中的var值)
{
var prop=type.GetProperty(value.Name);
if(prop==null)
{
WriteLine(string.Format(“没有为{0}找到公共属性”,value));
继续;
}
尝试
{
属性设置值(obj,value.value,null);
}
捕获(例外情况除外)
{
Debug.WriteLine(“异常设置”+value.ToString()+”:\n“+ex.ToString());
}
}
}
}

这将使用所有字符串值的属性名称和值填充数组。您可能需要更智能的东西,在这种情况下,手动填充数组,使用指示要导出的属性的自定义属性标记属性,或者其他更合适的方法。

我假设您正在使用。是吗?@dbc是的,是的。我认为情况就是这样。谢谢但是,这是可行的,我认为一种更简单的方法(至少对于我的实现来说)是创建一个“Value”类,将结果存储在数组中,然后使用Linq将属性引用的Getter(例如,
public string ID{get{return myValues.FirstOrDefault(v=>v.Name==“ID”);}
)放入数组中。[XmlText是解决我问题的关键。这使您可以在元素中放入值,而无需将该变量名变为新元素。
public static class NameValuePairExtensions
{
    public static List<NameValuePair> GetNamedValues<T>(T obj)
    {
        if (obj == null)
            throw new ArgumentNullException();
        var type = obj.GetType();
        var properties = type.GetProperties();
        List<NameValuePair> list = new List<NameValuePair>();
        foreach (var prop in properties)
        {
            if (prop.PropertyType == typeof(string))
            {
                var getter = prop.GetGetMethod();
                var setter = prop.GetSetMethod();

                if (getter != null && setter != null) // Confirm this property has public getters & setters.
                {
                    list.Add(new NameValuePair() { Name = prop.Name, Value = (string)getter.Invoke(obj, null) });
                }
            }
        }
        return list;
    }

    public static void SetNamedValues<T>(T obj, IEnumerable<NameValuePair> values)
    {
        if (obj == null || values == null)
            throw new ArgumentNullException();
        var type = obj.GetType();
        foreach (var value in values)
        {
            var prop = type.GetProperty(value.Name);
            if (prop == null)
            {
                Debug.WriteLine(string.Format("No public property found for {0}", value));
                continue;
            }
            try
            {
                prop.SetValue(obj, value.Value, null);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception setting " + value.ToString() + " : \n" + ex.ToString());
            }
        }
    }
}