XNA: Лучший способ загрузиться и считать XML-файл?

Я испытываю затруднения при выполнении этой на вид простой задачи. Я хочу загрузить XML-файлы той же простотой загрузки художественных активов:

        content  = new ContentManager(Services);
        content.RootDirectory = "Content";
        Texture2d background = content.Load("images\\ice");

Я не уверен, как сделать это. Это учебное руководство кажется полезным, но как я получаю a StorageDevice экземпляр?

У меня действительно есть что-то работающее теперь, но это чувствует симпатичный hacky:

public IDictionary Get(string typeName)
        {
            IDictionary result = new Dictionary();
            xmlReader.Read(); // get past the XML declaration

            string element = null;
            string text = null;

            while (xmlReader.Read())
            {

                switch (xmlReader.NodeType)
                {
                    case XmlNodeType.Element:
                        element = xmlReader.Name;
                        break;
                    case XmlNodeType.Text:
                        text = xmlReader.Value;
                        break;
                }

                if (text != null && element != null)
                {
                    result[element] = text;
                    text = null;
                    element = null;
                }

            }
            return result;
        }

Я применяю это к следующему XML-файлу:



  
    100
    23
    12
    2
  

И это может передать этот модульный тест:

    internal virtual IPersistentState CreateIPersistentState(string fullpath)
    {
        IPersistentState target = new ReadWriteXML(File.Open(fullpath, FileMode.Open));
        return target;
    }

    /// 
    ///A test for Get with one zombie.
    ///
    //[TestMethod()]
    public void SimpleGetTest()
    {
        string fullPath = "C:\\pathTo\\Data\\SavedZombies.xml";
        IPersistentState target = CreateIPersistentState(fullPath);
        string typeName = "zombie"; 

        IDictionary expected = new Dictionary();
        expected["health"] = "100";
        expected["positionX"] = "23";
        expected["positionY"] = "12";
        expected["speed"] = "2";

        IDictionary actual = target.Get(typeName);

        foreach (KeyValuePair entry in expected)
        {
            Assert.AreEqual(entry.Value, expected[entry.Key]);
        }
    }

Оборотные стороны к текущему подходу: загрузка файла сделана плохо, и соответствие ключам к значениям кажется, что это - путь больше усилия, чем необходимый. Кроме того, я подозреваю, что этот подход развалился бы больше чем с одной записью в XML.

Я не могу предположить, что это - оптимальная реализация.

ОБНОВЛЕНИЕ: Следуя совету @Peter Lillevold, я изменил это немного:

    public IDictionary Get(string typeName)
    {
        IDictionary result = new Dictionary();

        IEnumerable zombieValues = root.Element(@typeName).Elements();

        //result["health"] = zombie.Element("health").ToString();

        IDictionary nameToElement = zombieValues.ToDictionary(element => element.Name.ToString());

        foreach (KeyValuePair entry in nameToElement)
        {
            result[entry.Key] = entry.Value.FirstNode.ToString();
        }

        return result;
    }

    public ReadWriteXML(string uri)
    {
        root = XElement.Load(uri);
    }

    internal virtual IPersistentState CreateIPersistentState(string fullpath)
    {
        return new ReadWriteXML(fullpath);
    }

    /// 
    ///A test for Get with one zombie.
    ///
    [TestMethod()]
    public void SimpleGetTest()
    {
        IPersistentState target = CreateIPersistentState("../../../path/Data/SavedZombies.xml");
        string typeName = "zombie"; 

        IDictionary expected = new Dictionary();
        expected["health"] = "100";
        expected["positionX"] = "23";
        expected["positionY"] = "12";
        expected["speed"] = "2";

        IDictionary actual = target.Get(typeName);

        foreach (KeyValuePair entry in expected)
        {
            Assert.AreEqual(entry.Value, actual[entry.Key]);
        }
    }

Загрузка является все еще довольно дрянной, и так или иначе я не смог получить короткое ToDictionary работать с теми двумя лямбдами. Я должен был обратиться к тому циклу foreach. Что я делаю неправильно там?

7
задан Nick Heiner 14 March 2010 в 02:50
поделиться

2 ответа

Существует также новый и блестящий XElement (который является спортивным Linq to XML). Этот пример загрузит xml файл, найдет зомби и сбросит значения в словарь:

var doc = XElement.Load("filename");
var zombieValues = doc.Element("zombie").Elements();
var zombieDictionary = 
    zombieValues.ToDictionary(
        element => element.Name.ToString(), 
        element => element.Value);

Если вы предпочитаете выбирать каждое значение явно (и использовать кастинг для автоматического преобразования в нужные типы значений), вы можете сделать так:

var zombie = doc.Element("zombie");
var health = (int)zombie.Element("health");
var positionX = (int)zombie.Element("positionX");
var positionY = (int)zombie.Element("positionY");
var speed = (int)zombie.Element("speed");

Обновление: Исправив некоторые опечатки и немного почистив, ваш метод Get должен выглядеть так:

public IDictionary<string, string> Get(string typeName)
{
    var zombie = root.Element(typeName);
    return zombie.Elements()
          .ToDictionary(
                  element => element.Name.ToString(),
                  element => element.Value);
}
8
ответ дан 7 December 2019 в 01:19
поделиться
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(xmlString);

string health = doc["zombies"]["zombie"]["health"].InnerText;
// etc..

// or looping

foreach( XmlNode node in doc["zombies"].ChildNodes )
{
    string health = node["health"].InnerText;
    // etc...
}

Или это не работает в XNA?

2
ответ дан 7 December 2019 в 01:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: