【发布时间】: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