使用 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();
    }
}