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

Pass string variable to XmlAttribute of 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 建议对设计进行改进。

您可以使用 [XmlAnyAttribute] for this purpose. It specifies that the member (a field that returns an array of XmlAttribute 对象)可以包含任何 XML 属性。 请注意,可以使用 属性 以及一个字段来构造和 return 具有所需名称和值的单个属性:

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

XmlConvert.EncodeLocalName() is required in cases where the type string is not a valid XML name。例如,有效的 XML 名称必须以字母而非数字开头。

例子fiddle.

但是,如果需要,使用 type="drink" name="tea" 等固定属性可能会更容易在以后创建 XML 架构,因此您可能会重新考虑您的设计。 [XmlAnyAttribute] 对应于架构元素 xsd:anyAttribute,它允许出现任意数量的任意名称的属性。您可能希望为您的 <OwnedObjects> 元素指定一个任意名称的属性。