可以在每个元素上创建不同的属性吗?

时间:2016-09-16 04:27:26

标签: c# xml xml-serialization

需要帮助!

我的代码很快就完成了:

[XmlRoot("monster")]
public class monster
{
    public List<flag> flags { get; set; }
}

public class flag
{
    [XmlAttribute("summonable")]
    public int summonable { get; set; }

    [XmlAttribute("attackable")]
    public int attackable { get; set; }
}

 public void XML()
 { monster monster = new monster
            {
                flags = new List<flag>
                {
                    new flag() { summonable = 0 },
                    new flag() { attackable = 0 }
                }
            };
 }

他出来很好,我使用List&lt;&gt; :

<monster>
 <flags>
  <flag summonable="0" attackable="0" />
  <flag summonable="0" attackable="0" />
</flags>
</monster>

我需要这样:

<monster>
<flags>
    <flag summonable="0"/>
    <flag attackable="0"/>
</flags>
</monster>

感谢所有帮助过我的人...抱歉我的英语不好

3 个答案:

答案 0 :(得分:1)

我猜你可以通过用flag标记abstract类并按以下方式在两个类中派生它来做你需要的事情:

public abstract class flag
{

}

public class summonableFlag : flag
{
    [XmlAttribute("summonable")]
    public int summonable { get; set; }
}

public class attackableFlag : flag
{
    [XmlAttribute("attackable")]
    public int attackable { get; set; }
}

然后,您需要使用List<flag>标记XmlElementAttribute,将您的商品序列化为flag

[XmlRoot("monster")]
public class monster
{
    [XmlElement(elementName: "flag")]
    public List<flag> flags { get; set; }
}

最后,您的monster对象的创建将如下所示:

 monster monster = new monster
            {
                flags = new List<flag>
                {
                    new summonableFlag() { summonable = 0 },
                    new attackableFlag() { attackable = 0 }
                }
            };

在此之后我相信你会得到所需的结果。我没有测试过,所以如果你对这个解决方案有疑问,请写信。

答案 1 :(得分:1)

首先,由于您的标记集已修复,我不建议在List<flag>类中使用monster。相反,我会有一个flag对象,如下所示:

[XmlRoot("monster")]
public class monster
{
    public flags flags { get; set; }
}

public class flags
{
    public int summonable { get; set; }

    public int attackable { get; set; }

    // Add more as required.
}

现在,要根据需要将其序列化为XML,您可以引入一个public Flag[] Flags属性,使用固定属性的名称和值填充该属性。反过来,可以使用属性名称和值填充[XmlAnyAttribute]属性数组,如下所示:

[XmlRoot("monster")]
public class monster
{
    public flags flags { get; set; }
}

public class flags
{
    const string SummonableName = "summonable"; // In c# 6.0 use nameof(summonable)
    const string AttackableName = "attackable"; // See  https://msdn.microsoft.com/en-us/library/dn986596.aspx

    [XmlIgnore]
    public int summonable { get; set; }

    [XmlIgnore]
    public int attackable { get; set; }

    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
    [XmlElement("flag")]
    public Flag[] Flags
    {
        get
        {
            return new[]
            {
                new Flag { Name = SummonableName, Value = XmlConvert.ToString(summonable) },
                new Flag { Name = AttackableName, Value = XmlConvert.ToString(attackable) },
            };
        }
        set
        {
            if (value == null)
                return;
            foreach (var attr in value)
            {
                if (attr.Name == SummonableName)
                    summonable = XmlConvert.ToInt32(attr.Value);
                else if (attr.Name == AttackableName)
                    attackable = XmlConvert.ToInt32(attr.Value);
            }
        }
    }
}

public class Flag
{
    [XmlIgnore]
    public string Name { get; set; }

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

    [XmlAnyAttribute]
    public XmlAttribute[] XmlAttributes
    {
        get
        {
            var attr = new XmlDocument().CreateAttribute(Name.ToString());
            attr.Value = Value;
            return new [] { attr };
        }
        set
        {
            if (value == null || value.Length == 0)
            {
                Name = null;
                Value = null;
            }
            else if (value.Length == 1)
            {
                Name = value[0].Name;
                Value = value[0].Value;
            }
            else
            {
                throw new ArgumentException("Too many attributes");
            }
        }
    }
}

然后XML将如下所示:

<monster>
  <flags>
    <flag summonable="0" />
    <flag attackable="0" />
  </flags>
</monster>

示例fiddle

答案 2 :(得分:0)

您正在将属性名称与属性值混合。我相信可以帮助你的是:

[XmlRoot("monster")]
public class monster
{
    public List<flag> flags { get; set; }
}

public class flag
{
    [XmlAttribute("Name")]
    public string Name { get; set; }

    [XmlAttribute("Value")]
    public string Value { get; set; }

}



public void XML() { 
    monster monster = new monster
    {
            flags = new List<flag>
            {
                new flag() { Name="summonable", Value = 0 },
                new flag() { Name="attackable", Value =0 }
            }
        };
     }

哪个应该产生你需要的东西

<monster>
 <flags>
  <flag Name="Summonable" Value="0" />
  <flag Name="Attackable" Value="0" />
</flags>
</monster>