【问题标题】:Efficiently fetching information from .xml files and make them available to other methods有效地从 .xml 文件中获取信息并使其可用于其他方法
【发布时间】:2020-11-09 13:43:43
【问题描述】:

首先,如果我混淆了一些术语或忽略了一些非常明显的方法,我很抱歉,但我在 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 反序列化,但我无法使给定 here 的示例工作(我尝试从 TextReader 进行反序列化)。

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

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

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

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

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

【问题讨论】:

  • 您要查找的关键字是序列化和反序列化。 C#/ .NET 内置了多种工具来将您的对象序列化和反序列化为 XML。看看here
  • 你有没有架构。有时模式位置是 XML 的第二行上的 URL。您可以使用浏览器并转到页面并获取架构。然后有一些工具可以将架构转换为 c# 类。通常在使用 XML 序列化存在问题的地方,命名空间不正确。
  • 您好,感谢您的快速答复。是的,我已经尝试按照here 的描述使用来自文本阅读器的反序列化,但是我遇到了一个我不知道如何解决的问题。在方法和给定的示例 xml 文件中定义了 XmlElement(Namespace) 属性,但我尝试反序列化的 xml 中没有这些属性。
  • 你的xml有前缀吗?前缀必须与命名空间 URL 匹配。有时有一个没有前缀的命名空间,然后你必须在类中包含这个前缀。
  • 目前我正在尝试以下操作:因为我找到了 .xsd 架构,所以我使用 xsd.exe 将其转换为 cs。这或多或少都很好。现在我把整个事情都绘制好了,但我有点迷失了如何使用它从提供的 .xml 文件中获取信息。

标签: c# xml deserialization


【解决方案1】:

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

【讨论】:

  • 嘿,给小费。但是我想在每次运行程序时从不同的 .xml 加载数据。所有 xml 文件都是由同一个程序创建的,并且都应该遵循相同的模式,但是正如我在编辑中所描述的那样,我目前无法反序列化 .xml 文件。您的解决方案似乎只有在我想每次都从同一个 .xml 加载数据时才可行,还是我在这方面弄错了?
  • 没有。当您执行此操作时,Visual Studio 会创建一个类定义,您可以将其与 Xml 序列化程序一起使用,以加载与您用于将 XML 粘贴为类的文件具有相同结构的任何 XML 文件。
  • 啊我现在明白了,可悲的是,反序列化抛出了一个内部异常“InvalidOperationException:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-01
  • 1970-01-01
  • 2020-01-05
  • 1970-01-01
  • 2017-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多