C#中的多级XML文件读取

时间:2014-01-21 02:32:04

标签: c# xml-parsing

我想读取多级xml文件并将其存储在对象列表中。 XML文件保存性别,而性别又保持0到n attributemodifier和0-n技能修饰符。人们可以假设attributemodifiers resp。 skillmodifiers标记将始终存在。它无法加载子节点“attributemodifiers”和“skillmodifiers”,我的问题就是原因。

<?xml version="1.0" encoding="UTF-8"?>
<genders>
    <gender>
        <name>Female</name>
        <attributemodifiers>
            <attributemodifier>
                <attribute>Agility</attribute>
                <value>1</value>
            </attributemodifier>
        </attributemodifiers>       
        <skillmodifiers>
            <skillmodifier>
                <attribute>Charm</attribute>
                <value>1</value>
            </skillmodifier>
        </skillmodifiers>
    </gender>
    <gender>
        <name>Male</name>
        <attributemodifiers>
            <attributemodifier>
                <attribute>Strength</attribute>
                <value>1</value>
            </attributemodifier>
            <attributemodifier>
                <attribute>Focus</attribute>
                <value>-1</value>
            </attributemodifier>
        </attributemodifiers>       
        <skillmodifiers>
            <skillmodifier>
                <attribute>Intimidation</attribute>
                <value>1</value>
                <attribute>Coercion</attribute>
                <value>1</value>
            </skillmodifier>
        </skillmodifiers>
    </gender>
</genders>

我目前的代码:

XmlDocument doc = new XmlDocument ();
doc.Load (@"genders.xml");

XmlNodeList gs = doc.SelectNodes ("genders/gender");

foreach (XmlNode g in gs) {

    Gender tg = new Gender ();
    tg.Name = g.SelectSingleNode("name").InnerText;
    tg.Desc = g.SelectSingleNode("desc").InnerText;

    XmlNodeList ams = doc.ChildNodes;

    foreach (XmlNode am in ams) {
        int ta = (int)System.Enum.Parse(typeof(AttributeName), am.SelectSingleNode ("attribute").InnerText);
        int tv = System.Convert.ToInt32(am.SelectSingleNode ("value").InnerText);
        tg.AddAttributeModifier (ta, tv);
    }

    XmlNodeList sms = doc.ChildNodes;

    foreach (XmlNode sm in sms) {
        int ts = (int)System.Enum.Parse(typeof(SkillName), sm.SelectSingleNode ("skill").InnerText);
        int tv = System.Convert.ToInt32(sm.SelectSingleNode ("value").InnerText);
        tg.AddSkillModifier (ts, tv);
    }

    genders.Add (tg);
    length++;

    Debug.Log ("Increased length by 1, length is now " + length);
}

注释我的内部for循环将给出3的长度,因此代码失败的部分是子节点。

NullReferenceException: Object reference not set to an instance of an object
GenderManager.Awake () (at Assets/Scripts/Managers/GenderManager.cs:36)

哪个是

int ta = (int)System.Enum.Parse(typeof(AttributeName), am.SelectSingleNode ("attribute").InnerText);

那一行

我将假设ChildNodes的工作方式与我期望它的工作方式不同。

性别等级(gender.cs)

using System.Collections.Generic;

public class Gender {

    private string _name;
    private string _desc;
    private List<GenderBonusAttribute> _attributeMods;
    private List<GenderBonusSkill> _skillMods;

    public Gender () {
        _name = string.Empty;
        _attributeMods = new List<GenderBonusAttribute> ();
        _skillMods = new List<GenderBonusSkill> ();
    }

    public string Name {
        get {return _name;}
        set {_name = value;}
    }

    public string Desc {
        get {return _desc;}
        set {_desc = value;}
    }

    public void AddAttributeModifier (int a, int v) {
        _attributeMods.Add (new GenderBonusAttribute (a, v));
    }

    public void AddSkillModifier (int s, int v) {
        _skillMods.Add (new GenderBonusSkill (s, v));
    }

    public List<GenderBonusAttribute> AttributeMods {
        get {return _attributeMods;}
    }

    public List<GenderBonusSkill> SkillMods {
        get {return _skillMods;}
    }
}

public class GenderBonusAttribute {
    public int attribute;
    public int value;

    public GenderBonusAttribute (int a, int v) {
        attribute = a;
        value = v;
    }
}

public class GenderBonusSkill {
    public int skill;
    public int value;

    public GenderBonusSkill (int s, int v) {
        skill = s;
        value = v;
    }
}

编辑:添加了AttributeName和SkillName

public enum AttributeName {
    Strength,
    Agility,
    Quickness,
    Endurance,
    Attunement,
    Focus
};

public enum SkillName {
    Weight_Capacity,
    Attack_Power,
    Intimidation,
    Coercion,
    Charm
}

编辑#2:如果我手动添加他们的值的性别,它是有效的,所以我99.8%确定它是foreach循环不工作,这让我非常肯定doc.Childnodes没有按照我期望的方式工作他们工作。

1 个答案:

答案 0 :(得分:1)

为什么在循环中使用doc.ChildNodes,而不使用当前的gender元素?

amssms声明更改为:

XmlNodeList ams = g.SelectNodes("attributemodifiers/attributemodifier");
XmlNodeList sms = g.SelectNodes("skillmodifiers/skillmodifier");

PS。您不使用LINQ to XML的任何特殊原因?使用LINQ会更容易。