繁体   English   中英

使用XML来(解析?)多个不同类中的元素C#

[英]Using an XML to (parse?) elements in multiple different classes C#

如果答案以其他名字存在,我真的很抱歉,但是我一直试图找出一个星期左右,并且没有发现任何类似的东西。

因此,我正在为一个游戏构建一个物品系统。 有一个具有这些属性的Item类

public int ItemId;
public string ItemName;

为简单起见,假设我要有两个派生类,即Weapon和Armor,其中Weapon具有BaseDamage属性,而Armor具有BaseArmor。

我还想从XML加载项目到ItemContainer类中,理想情况下,是从同一个XML文件而不是用于武器,用于装甲和用于药水的项目。

我已经尝试了多种方法,但是到目前为止,我唯一能够成功的方法是将BaseDamage和BaseArmor添加到Item基类中,如下所示:

public class Item
{
    [XmlAttribute("ID")] public int ItemID;
    [XmlElement("Name")] public string ItemName;
    [XmlElement("Damage")] public int ItemBaseDamage;
    [XmlElement("Armor")] public int ItemBaseArmor;
}

并且只是不将某些项目的元素添加到XML文件中:

<ItemCollection>
  <Items>

    <Item ID ="001">
      <Name>Dagger</Name>
      <Damage>10</Damage>
    </Item>

    <Item ID ="002">
      <Name>Chain Mail</Name>
      <Armor>5</Armor>
    </Item>

  </Items>
</ItemCollection>

它确实有效,但是我觉得这不是正确的方法。 另一个问题是,如果我想添加一个具有某个函数的Scroll类以转换在该滚动条上写入的咒语,则需要向基类添加“ SpellToCast”属性,并向其添加CastSpell(Spell)函数可以从任何项目中调用,这不是我想要的...

简而言之,我想从XML加载多个项目,但每个项目都是其预期的派生类,以便它们能够访问各自的功能并获得其特定属性,例如BaseDamage(如果有的话)。

我尝试使用类型类别为ItemClass的XmlElement,但出现一条错误消息称XmlElement / XmlAttribute在此声明类型上无效...

我还考虑过使用抽象的Item类,但是如何将Item ID加载到抽象基类Item,然后将BaseDamage加载到派生类Weapon?

这是我用来(反序列化?我不确定这是正确的术语)XML文件的代码:

[XmlRoot("ItemCollection")]
public class ItemContainer
{
    [XmlArray("Items")]
    [XmlArrayItem("Item")]
    public List<Item> items = new List<Item>();

    public static ItemContainer Load(string itemPath)
    {
        TextAsset _xml = Resources.Load<TextAsset>(itemPath);

        XmlSerializer serializer = new XmlSerializer(typeof(ItemContainer));

        StringReader reader = new StringReader(_xml.text);

        ItemContainer items = serializer.Deserialize(reader) as ItemContainer;

        reader.Close();

        return items;
    }
}

因此,欢迎任何帮助,

谢谢

试试这个代码示例,一个适合xml和c#的好工具是xml2csharp

class Program
{
    static void Main(string[] args)
    {
        var xml = File.ReadAllText("test.xml");
        var serializer = new XmlSerializer(typeof(ItemCollection));
        using (var reader = new StringReader(xml))
        {
            var items = serializer.Deserialize(reader) as ItemCollection;
        }          
    }
}

[XmlRoot(ElementName = "Item")]
public class Item
{
    [XmlElement(ElementName = "Name")]
    public string Name { get; set; }
    [XmlElement(ElementName = "Damage")]
    public string Damage { get; set; }
    [XmlAttribute(AttributeName = "ID")]
    public string ID { get; set; }
    [XmlElement(ElementName = "Armor")]
    public string Armor { get; set; }
}

[XmlRoot(ElementName = "Items")]
public class Items
{
    [XmlElement(ElementName = "Item")]
    public List<Item> Item { get; set; }
}

[XmlRoot(ElementName = "ItemCollection")]
public class ItemCollection
{
    [XmlElement(ElementName = "Items")]
    public Items Items { get; set; }
}

虽然第一个答案并非我真正想要的答案,但是当我尝试使用多个词根时,它的确使我走上了正确的轨道,并且通过谷歌搜索,我进入了某个网站,意识到解决方案只是在告诉我XML文件,我将不使用Item类,而是使用Weapon / Armor / Scroll等,以便可以将它们视为各自的派生类。

这样吗:

[XmlRoot("ItemCollection")]
public class ItemContainer
{
    [XmlArray("Items")]
    [XmlArrayItem("Weapon", Type = typeof(Weapon))]
    [XmlArrayItem("Armor", Type = typeof(Armor))]
    public List<Item> items = new List<Item>();

    public static ItemContainer LoadItems(string itemPath)
    {
        TextAsset _xml = Resources.Load<TextAsset>(itemPath);

        XmlSerializer serializer = new XmlSerializer(typeof(ItemContainer));

        StringReader reader = new StringReader(_xml.text);

        ItemContainer items = serializer.Deserialize(reader) as ItemContainer;

        reader.Close();

        return items;
    }
}

我没有看过protoBuff,我发现的唯一东西就是协议缓冲区,这似乎就是您在谈论的内容。 我会牢记这一点,但就我目前对C#的基本理解而言,现在可能有点过头了

<?xml version="1.0" encoding="utf-8" ?>

<ItemCollection>
  <Items>

    <Weapon Name ="Dagger">
      <ID>01</ID>
      <BaseDamage>10</BaseDamage>
    </Weapon>

    <Armor Name ="Chainmail">
      <ID>04</ID>
      <BaseArmor>5</BaseArmor>
    </Armor>

  </Items>
</ItemCollection>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM