将字符串变量传递给XMLSerializer的XmlAttribute

时间:2017-01-19 08:49:23

标签: c# xmlserializer

假设我有以下代码,并希望在代码下面序列化为XML:

class Human
{
    [XmlElement("OwnedObjects")]
    public List<WorldObjects> ownedObjects;
}

class WorldObjects
{
    [XmlIgnore]
    public string type;
    [XmlAttribute(type)]
    public string name;

    public WorldObjects(string _type, string _name)
    {
        type = _type;
        name = _name;
    }
}

Human bob = new Human;
bob.ownedObjects = new List<WorldObjects>;
bob.ownedObjects.Add(new WorldObjects(drink, tea));

// Serialize

XML:

<Human>
    <OwnedObjects drink="tea" />
</Human>

[XmlAttribute(type)]行会导致错误。

无论如何通过传递字符串变量来改变属性名称吗?

提前谢谢。

编辑:我必须道歉,我忽略了这么简单的解决方案。谢谢您的回答。 另外,感谢Ben和dbc建议改进设计。

1 个答案:

答案 0 :(得分:3)

您可以使用[XmlAnyAttribute]来实现此目的。它指定成员(返回XmlAttribute个对象数组的字段)可以包含任何XML属性。注意,可以使用属性以及构造和返回的字段。具有所需名称和值的单个属性:

public class WorldObjects
{
    [XmlAnyAttribute]
    public XmlAttribute [] Attributes
    {
        get
        {
            var attr = new XmlDocument().CreateAttribute(XmlConvert.EncodeLocalName(type));
            attr.Value = name;
            return new[] { attr };
        }
        set
        {
            var attr = (value == null ? null : value.SingleOrDefault());
            if (attr == null)
                name = type = string.Empty;
            else
            {
                type = XmlConvert.DecodeName(attr.Name);
                name = attr.Value;
            }
        }
    }

    [XmlIgnore]
    public string name;

    [XmlIgnore]
    public string type;

    // XmlSerializer required parameterless constructor
    public WorldObjects() : this(string.Empty, string.Empty) { }

    public WorldObjects(string _type, string _name)
    {
        type = _type;
        name = _name;
    }
}
如果type字符串不是XmlConvert.EncodeLocalName(),则需要

valid XML name。例如,有效的XML名称必须以字母开头,而不是数字。

示例fiddle

但是,如果需要,使用type="drink" name="tea"等固定属性可以让您更轻松地创建XML架构,因此您可能会重新考虑您的设计。 [XmlAnyAttribute]对应于架构元素xsd:anyAttribute,它允许显示任意名称的任意数量的属性。您可能希望指定<OwnedObjects>元素的任何名称必须只有一个属性。