首页 > 解决方案 > 有效地从 .xml 文件中获取信息并使其可用于其他方法

问题描述

首先,如果我混淆了一些术语或忽略了一些非常明显的方法,我很抱歉,但我在 C# 和 OOP 方面很新,这是我目前“自学”c# 的项目。这就是为什么我将分享我的大部分代码以希望消除一些不明确之处。

我不想从 .xml 文件中获取信息并以各种不同的方法使用这些信息。为此,我找到了一个我实施并且工作正常的解决方案,但有点笨拙。

我使用此方法从 XML 中读出我需要的所有内容:

 class ReadAndLoad
    {
        public List<CharacterAttributes> FetchAttributes(string userPath)
        {
            // Declare a new XML Document
            XmlDocument XmlDoc = new XmlDocument();

            // Try to open the XML file
            try
            {
                Console.WriteLine("\nNow Loading: {0}\n", userPath);
                XmlDoc.Load(userPath);
            }
            // Catch "File Not Found" errors
            catch (System.IO.FileNotFoundException)
            {
                Console.WriteLine("No file found!");
                Environment.Exit(1);
            }
            // Catch Argument Exceptions
            catch (System.ArgumentException)
            {
                Console.WriteLine("Invalid path detected!");
                Environment.Exit(1);
            }
            // Catach all other errors, and print them to console.
            catch (Exception err)
            {
                Console.WriteLine("An Exception has been caught:");
                Console.WriteLine(err);
                Environment.Exit(1);
            }

            // Declare the xpath for finding objects inside the XML file
            XmlNodeList XmlDocNodes = XmlDoc.SelectNodes("/character/attributes/attribute");

            // Define a new List, to store the objects we pull out of the XML
            List<CharacterAttributes> attributeList = new List<CharacterAttributes>();

            // Loop through the nodes, extracting Person information.
            // We can then define a person object and add it to the list.
            foreach (XmlNode node in XmlDocNodes)
            {
                int tempValue = int.Parse(node["totalvalue"].InnerText);
                CharacterAttributes obj = new CharacterAttributes(node["name"].InnerText, tempValue);
                attributeList.Add(obj);
            }

            for (int i = 0; i < attributeList.Count; i++)
            {
                Console.WriteLine(attributeList[i].AttributeName);
                Console.WriteLine(attributeList[i].TotalValue);
            }
            return attributeList;
        }

在构造函数中创建了一个具有所有属性的“字符类”

class Character
{
    //Attribute Fields
    public int Body { get; set; }
    public int Agility { get; set; }
    public int Reaction { get; set; }
    public int Strength { get; set; }
    public int Willpower { get; set; }
    public int Logic { get; set; }
    public int Intuition { get; set; }
    public int Charisma { get; set; }
    public int Edge { get; set; }
    public int Essence { get; set; }
    public int Resonance { get; set; }
    public int Magic { get; set; }

    //Attribute Constructor
    public Character(int xmlBody, int xmlAgility, int xmlReaction, int xmlStrength, int xmlIntuition, int xmlCharisma, int xmlLogic, int xmlWillpower, int xmlEdge, int xmlMagic, int xmlResonance, int xmlEssence)
    {

        this.Body = xmlBody;
        this.Agility = xmlAgility;
        this.Reaction = xmlReaction;
        this.Strength = xmlStrength;
        this.Intuition = xmlIntuition;
        this.Charisma = xmlCharisma;
        this.Logic = xmlLogic;
        this.Willpower = xmlWillpower;
        this.Edge = xmlEdge;
        this.Essence = xmlEssence;
        this.Resonance = xmlResonance;
        this.Magic = xmlMagic;
    }

为了创建一个角色,我创建了这个方法,它采用 ReadAndLoad.FetchAttributes 提供的列表并将它们提供给构造函数

class CreateCharacters
{
    public Character CreateCharacterFromXML(string userPath)
    {
        ReadAndLoad readAndLoad = new ReadAndLoad();

        List<CharacterAttributes> attributeList = new List<CharacterAttributes>();
        attributeList = readAndLoad.FetchAttributes(userPath);

        int bod = attributeList[0].TotalValue;
        int agi = attributeList[1].TotalValue;
        int rea = attributeList[2].TotalValue;
        int str = attributeList[3].TotalValue;
        int cha = attributeList[4].TotalValue;
        int intuition = attributeList[5].TotalValue;
        int log = attributeList[6].TotalValue;
        int wil = attributeList[7].TotalValue;
        int edg = attributeList[8].TotalValue;
        int mag = attributeList[9].TotalValue;
        int res = attributeList[11].TotalValue;
        int ess = attributeList[12].TotalValue;

        Character myCharacter = new Character(bod, agi, rea, str, cha, intuition, log, wil, edg, mag, res, ess);

        return myCharacter;
    }
}

我觉得有一种更优雅、更有效的方法可以做到这一点,使用来自同一 XML 的更多数据更容易扩展。因为目前如果我想引入一些其他数据,我必须创建一个新的 ReadAndLoad 方法,该信息的新类,扩展字符类和构造函数并将所有内容添加到 CreateCharacter 方法中。

有人将我指向 xml 反序列化,但我无法使此处给出的示例正常工作(我尝试从 TextReader 进行反序列化)。

我试图反序列化/从中获取信息的 xml 没有提供作为 url 的架构,因为我真的不知道如何反序列化它。下面给出的是xml的开始。

经过一番搜索,我找到了可能为我提供了正确架构的架构 .xsd。

遗憾的是,由于我找不到 .xsd 中的错误,目前无法进行反序列化。

我尝试用于反序列化的 .xsd 引用了另一个似乎包含错误的 .xsd,这导致某些元素未被声明。

遗憾的是,InteliSense 没有提供有关该错误的任何信息。

标签: c#xmldeserialization

解决方案


执行此操作的超级简单方法是将 XML 文档复制到剪贴板并在 C# 代码文件中将 XML 粘贴为类:

在此处输入图像描述


推荐阅读