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

C# 使用XML来(解析?)多个不同类C中的元素#,c#,xml,serialization,C#,Xml,Serialization,如果答案是以另一个名字出现的,我真的很抱歉,但我已经试着找出这个问题一周左右了,没有发现任何类似的问题 所以,我正在为unity游戏建立一个项目系统。有一个具有这些属性的Item类 public int ItemId; public string ItemName; 为了简单起见,假设我想要两个派生类,武器和装甲,武器和装甲分别有一个BaseDamage属性和一个BaseArmor属性 我还希望从XML加载ItemContainer类中的项目,理想情况下,从相同的XML文件加载,而不是一个用于

如果答案是以另一个名字出现的,我真的很抱歉,但我已经试着找出这个问题一周左右了,没有发现任何类似的问题

所以,我正在为unity游戏建立一个项目系统。有一个具有这些属性的Item类

public int ItemId;
public string ItemName;
为了简单起见,假设我想要两个派生类,武器和装甲,武器和装甲分别有一个BaseDamage属性和一个BaseArmor属性

我还希望从XML加载ItemContainer类中的项目,理想情况下,从相同的XML文件加载,而不是一个用于武器,一个用于盔甲,一个用于药剂

我已经尝试了多种方法,但到目前为止,我唯一能够成功的方法是将基础伤害和基础护甲添加到物品基类中。。。像这样:

public class Item
{
    [XmlAttribute("ID")] public int ItemID;
    [XmlElement("Name")] public string ItemName;
    [XmlElement("Damage")] public int ItemBaseDamage;
    [XmlElement("Armor")] public int ItemBaseArmor;
}
[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;
    }
}
对于某些项目,只需不将元素添加到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>

匕首
10
连锁邮件
5.
这确实有效,但我觉得这不是正确的方法。另一个问题是,如果我想添加一个具有特定函数的Scroll类来施放写在该滚动上的咒语,我需要将“SpellToCast”属性添加到基类中,并向其添加一个可以从任何项目调用的CastSpell(spell)函数,这不是我想要的

简而言之,我想从XML中加载多个项,但每个项都是它们预期的派生类,这样它们就可以访问各自的函数并获得特定的属性,如BaseDamage(如果是武器)

我尝试使用类型为class的名为ItemClass的XmlElement,但我得到一个错误,指出XmlElement/XmlAttribute在此声明类型上无效

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

这是我用来(反序列化?我不确定这是正确的术语)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;
    }
}
[XmlRoot(“ItemCollection”)]
公共类ItemContainer
{
[XmlArray(“项”)]
[XmlArrayItem(“项目”)]
公共列表项=新列表();
公共静态ItemContainer加载(字符串itemPath)
{
TextAsset _xml=Resources.Load(itemPath);
XmlSerializer serializer=新的XmlSerializer(typeof(ItemContainer));
StringReader=新的StringReader(_xml.text);
ItemContainer items=序列化程序。将(读取器)反序列化为ItemContainer;
reader.Close();
退货项目;
}
}
所以,欢迎任何帮助


谢谢

试试这个代码示例,这是一个很好的xml和c语言工具

类程序
{
静态void Main(字符串[]参数)
{
var xml=File.ReadAllText(“test.xml”);
var serializer=newxmlserializer(typeof(ItemCollection));
使用(var reader=newstringreader(xml))
{
var items=serializer.将(读取器)反序列化为ItemCollection;
}          
}
}
[XmlRoot(ElementName=“Item”)]
公共类项目
{
[xmlement(ElementName=“Name”)]
公共字符串名称{get;set;}
[XmlElement(ElementName=“损坏”)]
公共字符串损坏{get;set;}
[XmlAttribute(AttributeName=“ID”)]
公共字符串ID{get;set;}
[XmlElement(ElementName=“Armor”)]
公共字符串{get;set;}
}
[XmlRoot(ElementName=“Items”)]
公共类项目
{
[xmlement(ElementName=“Item”)]
公共列表项{get;set;}
}
[XmlRoot(ElementName=“ItemCollection”)]
公共类项目集合
{
[xmlement(ElementName=“Items”)]
公共项目{get;set;}
}

试试这个代码示例,这是一个很好的xml和c语言工具

类程序
{
静态void Main(字符串[]参数)
{
var xml=File.ReadAllText(“test.xml”);
var serializer=newxmlserializer(typeof(ItemCollection));
使用(var reader=newstringreader(xml))
{
var items=serializer.将(读取器)反序列化为ItemCollection;
}          
}
}
[XmlRoot(ElementName=“Item”)]
公共类项目
{
[xmlement(ElementName=“Name”)]
公共字符串名称{get;set;}
[XmlElement(ElementName=“损坏”)]
公共字符串损坏{get;set;}
[XmlAttribute(AttributeName=“ID”)]
公共字符串ID{get;set;}
[XmlElement(ElementName=“Armor”)]
公共字符串{get;set;}
}
[XmlRoot(ElementName=“Items”)]
公共类项目
{
[xmlement(ElementName=“Item”)]
公共列表项{get;set;}
}
[XmlRoot(ElementName=“ItemCollection”)]
公共类项目集合
{
[xmlement(ElementName=“Items”)]
公共项目{get;set;}
}

虽然第一个答案并不完全是我想要的,但它确实让我走上了正确的道路,因为我研究了如何使用多个根,并通过谷歌搜索找到了答案,我在某个网站上发现,解决方案只是告诉XML文件我不会使用Item类,而是使用武器/装甲/卷轴等,这样它们就可以被视为各自的派生类

它是这样的:

public class Item
{
    [XmlAttribute("ID")] public int ItemID;
    [XmlElement("Name")] public string ItemName;
    [XmlElement("Damage")] public int ItemBaseDamage;
    [XmlElement("Armor")] public int ItemBaseArmor;
}
[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;
    }
}
[XmlRoot(“ItemCollection”)]
公共类ItemContainer
{
[XmlArray(“项”)]
[XmlArrayItem(“武器”,Type=typeof(武器))]
[XmlArrayItem(“装甲”,Type=typeof(装甲))]
公共列表项=新列表();
公共静态ItemContainer LoadItems(字符串itemPath)
{
TextAsset _xml=Resources.Load(itemPath);
XmlSerializer serializer=新的XmlSerializer(typeof(ItemContainer));
StringReader=新的StringReader(_xml.text);
ItemContainer items=序列化程序。将(读取器)反序列化为ItemContainer;
reader.Close();
退货项目;
}
}
我还没有看过protoBuff,我唯一发现的是协议缓冲区,这似乎就是你所说的。我会记住的,但现在对我的基本理解可能有点太多了