使用 C# 将困难的 XML 读入列表的最佳方法
best approach to read a difficult XML into a list with C#
我需要在 C# 中读取以下 XML 的值。这里的XML只是整个XML的一小部分。这是一个保存游戏。由于其复杂性,反序列化可能无法正常工作。
<Profession>
<StrengthSkills>
<strengthSkills size="3">
<i0>
<skillKey>25</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
<i1>
<skillKey>41</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i1>
<i2>
<skillKey>12</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i2>
</strengthSkills>
</StrengthSkills>
<DexteritySkills>
<dexteritySkills size="2">
<i0>
<skillKey>105</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
<i1>
<skillKey>131</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i1>
</dexteritySkills>
</DexteritySkills>
<IntelligenceSkills>
<intelligenceSkills size="1">
<i0>
<skillKey>208</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
</intelligenceSkills>
</IntelligenceSkills>
<CharismaSkills>
<charismaSkills size="2">
<i0>
<skillKey>304</skillKey>
<skillLevel>2</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
<i1>
<skillKey>309</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i1>
</charismaSkills>
</CharismaSkills>
<PerceptionSkills>
<perceptionSkills size="1">
<i0>
<skillKey>405</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
</perceptionSkills>
</PerceptionSkills>
<FortitudeSkills>
<fortitudeSkills size="1">
<i0>
<skillKey>500</skillKey>
<skillLevel>2</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
</fortitudeSkills>
</FortitudeSkills>
</Profession>
我真的很纠结这个问题。我希望这里有人可以帮助我。问题是值有节点(“i0”、“i1”等)似乎找不到解决它们的好方法。
这是我在 XML 的另一部分中使用的,效果很好:
public static List<GetSkills> SkillsList()
{
return XDocument.Load(ProcessFile.tempFilePath)
.Element("root")
.Element("FamilyMembers")
.Elements().Where(e => e.Name.LocalName.StartsWith("Member_"))
.Select(p => GetSkillsForMember(p))
.ToList();
}
但是如果我对 XML 的这一部分尝试相同的方法,我会在 <i0>
部分遇到困难。
我的目标是将值放入列表中,以便能够更改它们、添加具有新值的新 (ix) 节点,然后将它们放回 XML。输出 XML 遵循相同的构建非常重要。
我通过执行以下操作解决了它:
var skillsAmount = xDoc.Descendants("Profession").Descendants(skillType + "Skills").FirstOrDefault().Attribute("size").Value;
var skillNum = new[]
{
new {Nr = 14, Skill = "Str", Type = "strengthSkills"},
new {Nr = 12, Skill = "Dex", Type = "dexteritySkills"},
new {Nr = 17, Skill = "Int", Type = "intelligenceSkills"},
new {Nr = 13, Skill = "Cha", Type = "charismaSkills"},
new {Nr = 17, Skill = "Per", Type = "perceptionSkills"},
new {Nr = 20, Skill = "For", Type = "fortitudeSkills"}
}.ToList();
foreach (var num in skillNum)
{
for (int i = 0; i < Convert.ToInt32(skillsAmount); i++)
{
List<Skills> Skills = xDoc
.Descendants("Profession")
.Descendants(skillNum.Type)
.Descendants("i" + i)
.Select(q => new Skills()
{
SkillKey = q.Element("skillKey").Value,
SkillLevel = q.Element("skillLevel").Value
})
.ToList();
}
}
我需要在 C# 中读取以下 XML 的值。这里的XML只是整个XML的一小部分。这是一个保存游戏。由于其复杂性,反序列化可能无法正常工作。
<Profession>
<StrengthSkills>
<strengthSkills size="3">
<i0>
<skillKey>25</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
<i1>
<skillKey>41</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i1>
<i2>
<skillKey>12</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i2>
</strengthSkills>
</StrengthSkills>
<DexteritySkills>
<dexteritySkills size="2">
<i0>
<skillKey>105</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
<i1>
<skillKey>131</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i1>
</dexteritySkills>
</DexteritySkills>
<IntelligenceSkills>
<intelligenceSkills size="1">
<i0>
<skillKey>208</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
</intelligenceSkills>
</IntelligenceSkills>
<CharismaSkills>
<charismaSkills size="2">
<i0>
<skillKey>304</skillKey>
<skillLevel>2</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
<i1>
<skillKey>309</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i1>
</charismaSkills>
</CharismaSkills>
<PerceptionSkills>
<perceptionSkills size="1">
<i0>
<skillKey>405</skillKey>
<skillLevel>1</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
</perceptionSkills>
</PerceptionSkills>
<FortitudeSkills>
<fortitudeSkills size="1">
<i0>
<skillKey>500</skillKey>
<skillLevel>2</skillLevel>
<accuracyLevel>0</accuracyLevel>
<damageLevel>0</damageLevel>
<staminaLevel>0</staminaLevel>
<chanceLevel>0</chanceLevel>
</i0>
</fortitudeSkills>
</FortitudeSkills>
</Profession>
我真的很纠结这个问题。我希望这里有人可以帮助我。问题是值有节点(“i0”、“i1”等)似乎找不到解决它们的好方法。
这是我在 XML 的另一部分中使用的,效果很好:
public static List<GetSkills> SkillsList()
{
return XDocument.Load(ProcessFile.tempFilePath)
.Element("root")
.Element("FamilyMembers")
.Elements().Where(e => e.Name.LocalName.StartsWith("Member_"))
.Select(p => GetSkillsForMember(p))
.ToList();
}
但是如果我对 XML 的这一部分尝试相同的方法,我会在 <i0>
部分遇到困难。
我的目标是将值放入列表中,以便能够更改它们、添加具有新值的新 (ix) 节点,然后将它们放回 XML。输出 XML 遵循相同的构建非常重要。
我通过执行以下操作解决了它:
var skillsAmount = xDoc.Descendants("Profession").Descendants(skillType + "Skills").FirstOrDefault().Attribute("size").Value;
var skillNum = new[]
{
new {Nr = 14, Skill = "Str", Type = "strengthSkills"},
new {Nr = 12, Skill = "Dex", Type = "dexteritySkills"},
new {Nr = 17, Skill = "Int", Type = "intelligenceSkills"},
new {Nr = 13, Skill = "Cha", Type = "charismaSkills"},
new {Nr = 17, Skill = "Per", Type = "perceptionSkills"},
new {Nr = 20, Skill = "For", Type = "fortitudeSkills"}
}.ToList();
foreach (var num in skillNum)
{
for (int i = 0; i < Convert.ToInt32(skillsAmount); i++)
{
List<Skills> Skills = xDoc
.Descendants("Profession")
.Descendants(skillNum.Type)
.Descendants("i" + i)
.Select(q => new Skills()
{
SkillKey = q.Element("skillKey").Value,
SkillLevel = q.Element("skillLevel").Value
})
.ToList();
}
}