2016-09-16 67 views
-1

需要幫助,請!可以在每個元素上創建不同的屬性?

我的代碼是這樣做得風生水起:

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

他出來很好,我使用列表<>:

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

我需要這樣的:

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

感謝大家誰幫我...對不起,我的英文不好

+1

固定標誌值集合(即只有'summonable'和'attackable')還是可以有任何數量的標誌? – dbc

+0

只能召喚和攻擊 –

+0

如果是這樣的話,爲什麼不讓他們成爲你自己的元素?例如,? – Thumper

回答

1

首先,由於您的標誌設置是固定的,因此我不會在您的monster課程中推薦List<flag>。相反,我將有一個單一的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

+0

很好!有可能縮短代碼? –

+0

@GustavoBatista - 我想不到一個馬上就來。如果你的'flag'類具有很多屬性,那麼使用反射可能會更緊湊。你所做的有點違背了'XmlSerializer'的設計,該設計旨在使用反射將XML映射到元素和屬性。 – dbc

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> 
+0

我不想名字和價值 –

+0

這是不幸的,我不能幫你更多。另外兩個答案在這裏是相當不錯的,但要小心可維護性。 – Thumper

+0

非常感謝你 –

1

我想你可以做你的需要通過標記flagabstract和在推導它的兩個班通過以下方式:

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

這一點,我相信你會得到所要的結果之後。我還沒有測試過,所以如果你對這個解決方案有問題,請寫下來。

+0

你好,它的工作,但我如何取出命名空間?

+0

@GustavoBatista,那是一個單獨的問題,並要求我們知道您是如何生成XML的。 – Thumper

+0

非常感謝你 –

相關問題