【问题标题】:How to deserialize element with list of attributes in C#如何在 C# 中使用属性列表反序列化元素
【发布时间】:2015-10-01 09:43:42
【问题描述】:

您好,我有以下 Xml 需要反序列化:

<RootNode>
    <Item
      Name="Bill"
      Age="34"
      Job="Lorry Driver"
      Married="Yes" />
    <Item
      FavouriteColour="Blue"
      Age="12"
    <Item
      Job="Librarian"
       />
    </RootNote>

当我不知道键名或会有多少属性时,如何使用属性键值对列表反序列化 Item 元素?

【问题讨论】:

    标签: c# xml serialization attributes


    【解决方案1】:

    您可以使用XmlAnyAttribute 属性指定在使用XmlSerializer 时将任意属性序列化和反序列化为XmlAttribute [] 属性或字段。

    例如,如果您想将您的属性表示为 Dictionary&lt;string, string&gt;,您可以如下定义您的 ItemRootNode 类,使用代理 XmlAttribute[] 属性将字典从所需的字典转换为所需的字典XmlAttribute数组:

    public class Item
    {
        [XmlIgnore]
        public Dictionary<string, string> Attributes { get; set; }
    
        [XmlAnyAttribute]
        public XmlAttribute[] XmlAttributes
        {
            get
            {
                if (Attributes == null)
                    return null;
                var doc = new XmlDocument();
                return Attributes.Select(p => { var a = doc.CreateAttribute(p.Key); a.Value = p.Value; return a; }).ToArray();
            }
            set
            {
                if (value == null)
                    Attributes = null;
                else
                    Attributes = value.ToDictionary(a => a.Name, a => a.Value);
            }
        }
    }
    
    public class RootNode
    {
        [XmlElement("Item")]
        public List<Item> Items { get; set; }
    }
    

    原型fiddle

    【讨论】:

    • 谢谢,这正是我所追求的
    【解决方案2】:

    使用XmlDocument 类,您只需选择“项目”节点并遍历属性:

    string myXml = "<RootNode><Item Name=\"Bill\" Age=\"34\" Job=\"Lorry Driver\" Married=\"Yes\" /><Item FavouriteColour=\"Blue\" Age=\"12\" /><Item Job=\"Librarian\" /></RootNode>"
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(myXml);
    XmlNodeList itemNodes = doc.SelectNodes("RootNode/Item");
    foreach(XmlNode node in itemNodes)
    {
        XmlAttributeCollection attributes = node.Attributes;
        foreach(XmlAttribute attr in attributes)
        {
             // Do something...
        }
    }
    

    或者,如果你想要一个只包含属性作为 KeyValuePairs 列表的对象,你可以使用类似的东西:

    var items = from XmlNode node in itemNodes
                select new 
                {
                    Attributes = (from XmlAttribute attr in node.Attributes
                                  select new KeyValuePair<string, string>(attr.Name, attr.Value)).ToList()
                };
    

    【讨论】:

    • 谢谢我有现有的 xml 解析代码,但我想看看我是否可以使用 xml 序列化,因为它更整洁,我让它适用于除了属性之外的所有东西——我知道如何使用它已知命名属性是未知数量或属性名称的问题
    猜你喜欢
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多