反序列化与独特属性重复的XML元素 [英] Deserializing duplicate XML elements with unique attributes

查看:157
本文介绍了反序列化与独特属性重复的XML元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下XML结构:

 <应变及GT; 
<数值名称=ID> 1 LT; /价值与GT;
<数值名称=用户>&JSMITH LT; /价值与GT;
<数值名称=描述>测试123 LT; /价值与GT;
< /响应>

如何反序列化这使该值名称是对类属性和文本值该属性的值?



请注意,该值名称不会改变,所以名称=ID总会。存在的,例如:



下面是我班至今:

  [Serializable接口] 
[XmlRoot(回应)]
公共类ReportingResponse
{
// [善有善报吗?]
公共字符串ID {搞定;组; }

// [...]
公共字符串用户{搞定;组; }

// [...]
公共字符串描述{搞定;组; }
}


解决方案

这是XML的结构如名称/值对的集合,而不是与预定义属性的类,它会更容易和更自然的反序列化它是这样。



如果你决心反序列化到一个类,假设你使用的 的XmlSerializer ,你可以引入代理名称/值对数组用于这一目的,像这样:

 公共类的NameValuePair 
{
[ XmlAttribute]
公共字符串名称{;组; }

[XMLTEXT]
公共字符串值{获得;组; }

公共重写字符串的ToString()
{
返回的String.Format(NAME = {0},值= \{1} \,名称,值);
}
}

[Serializable接口]
[XmlRoot(回应)]
公共类ReportingResponse
{
[的XmlElement(的ElementName =值)]
[可浏览(假),EditorBrowsable(EditorBrowsableState.Never)
[DebuggerBrowsable(DebuggerBrowsableState.Never)
公众的NameValuePair [] XmlNameValuePairs
{
得到
{
返回NameValuePairExtensions.GetNamedValues(本).ToArray();
}

{
NameValuePairExtensions.SetNamedValues(这一点,值);
}
}

[XmlIgnore]
公共字符串ID {搞定;组; }

[XmlIgnore]
公共字符串用户{搞定;组; }

[XmlIgnore]
公共字符串描述{搞定;组; }
}



然后一些反射来自动加载数组:



 公共静态类NameValuePairExtensions 
{
公共静态列表<&的NameValuePair GT; GetNamedValues< T>(T OBJ)
{
如果(OBJ == NULL)
抛出新的ArgumentNullException();
变种类型= obj.GetType();
变种属性= type.GetProperties();
名单,LT;&的NameValuePair GT;名单=新名单,LT;&的NameValuePair GT;();
的foreach(在性能VAR道具)
{
如果(prop.PropertyType == typeof运算(字符串))
{
VAR吸气= prop.GetGetMethod();
VAR二传手= prop.GetSetMethod();

如果(吸气剂= NULL&放大器;!&安培;!二传手= NULL)//确认酒店有公共的getter和放大器; setter方法。
{
list.Add(新的NameValuePair(){名称= prop.Name,值=(字符串)getter.Invoke(OBJ,NULL)});
}
}
}
返回列表;
}

公共静态无效SetNamedValues< T>(T OBJ,IEnumerable的<的NameValuePair>的值)
{
如果(OBJ == NULL ||值== NULL)
抛出新的ArgumentNullException();
变种类型= obj.GetType();
的foreach(中值VAR值)
{
VAR道具= type.GetProperty(value.Name);
如果(道具== NULL)
{
的Debug.WriteLine(的String.Format(,值)找到{0}无公共财产);
继续;
}

{
prop.SetValue(OBJ,value.Value,NULL);
}
赶上(异常前)
{
的Debug.WriteLine(异常设定+ value.ToString()+:\\\
+ ex.ToString() );
}
}
}
}

这填充所有字符串值的属性名称和值的数组。你可能想要的东西更聪明,在这种情况下手动填充阵列,标注属性与自定义属性的说明要导出,或什么的,可能更合适。


I have the following XML structure:

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

How can I deserialize this so that the value names are properties on the class, and the text values are the values of the properties?

Note that the value names never change, so Name="ID" will always exist, for example.

Here is my class so far:

[Serializable]
[XmlRoot("Response")]
public class ReportingResponse
{
    // [What goes here?]
    public string ID { get; set; }

    // [...]
    public string User { get; set; }

    // [...]
    public string Description { get; set; }
}

解决方案

That XML is structured as a collection of name/value pairs rather than as a class with predefined properties, and it would be easier and more natural to deserialize it as such.

If you're determined to deserialize into a class, assuming you're using XmlSerializer, you could introduce a proxy array of name/value pairs for that purpose, like so:

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; }
}

And then some reflection to automatically load up the array:

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());
            }
        }
    }
}

This fills the array with all string-valued property names and values. You might want something more intelligent, in which case manually filling the array, labeling properties with a custom attribute indicating those to be exported, or whatever, might be more appropriate.

这篇关于反序列化与独特属性重复的XML元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆