Нужна помощь при загрузке данных XML в проект XNA 4.0 - PullRequest
0 голосов
/ 30 июня 2010

Я бы хотел сделать это правильно, если это возможно.У меня есть XML-данные следующим образом:

<?xml version="1.0" encoding="utf-8"?>
    <XnaContent>
        <Asset Type="PG2.Dictionary">
            <Letters TotalInstances="460100">
                <Letter Count="34481">&#97;</Letter>
                ...
                <Letter Count="1361">&#122;</Letter>
            </Letters>
            <Words Count="60516">
                <Word>aardvark</Word>
                ...
                <Word>zebra</Word>
            </Words>
        </Asset>
    </XnaContent>

, и я хотел бы загрузить их (используя Content.Load ) в один из этих

namespace PG2
{
    public class Dictionary
    {
        public class Letters
        {
            public int totalInstances;

            public List<Character> characters;

            public class Character
            {
                public int count;
                public char character;
            }
        }

        public class Words
        {
            public int count;
            public HashSet<string> words;
        }

        Letters letters;
        Words words;
    }
}

Может кто-нибудь помочьс инструкциями или указателями на учебники?Я обнаружил, что некоторые из них близки, но между 3,1 и 4,0 вещи, кажется, немного изменились способами, которые я не понимаю, и большая часть документации предполагает знания, которых у меня нет.Насколько я понимаю, мне нужно сделать класс Dictionary Serializable, но я не могу этого добиться.Я добавил файл XML в проект контента, но как мне получить его для создания правильного файла XNB?

Спасибо!Чарли.

Ответы [ 2 ]

1 голос
/ 30 июня 2010

Это может помочь http://blogs.msdn.com/b/shawnhar/archive/2009/03/25/automatic-xnb-serialization-in-xna-game-studio-3-1.aspx. Я считаю полезным работать наоборот, чтобы убедиться, что мои данные XML были правильно определены.Создайте свой словарный класс, установите все поля, затем сериализуйте его в xml, используя XmlSerializer для проверки вывода.

0 голосов
/ 16 сентября 2010

Вам необходимо реализовать ContentTypeSerializer для вашего класса Dictionary.Поместите это в библиотеку расширений контента и добавьте ссылку на библиотеку расширений контента в свой контент-проект.Поместите свой класс Dictionary в библиотеку игр, которая является справочной как по вашей игре, так и по проекту расширения контента.

См .: http://blogs.msdn.com/b/shawnhar/archive/2008/08/26/customizing-intermediateserializer-part-2.aspx

Вот небольшой написанный мной ContentTypeSerializer, который десериализует ваш Словарьучебный класс.Это могло бы использовать лучшую обработку ошибок.

using System;
using System.Collections.Generic;
using System.Xml;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate;

namespace PG2
{
    [ContentTypeSerializer]
    class DictionaryXmlSerializer : ContentTypeSerializer<Dictionary>
    {
        private void ReadToNextElement(XmlReader reader)
        {
            reader.Read();

            while (reader.NodeType != System.Xml.XmlNodeType.Element)
            {
                if (!reader.Read())
                {
                    return;
                }
            }
        }

        private void ReadToEndElement(XmlReader reader)
        {
            reader.Read();

            while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
            {
                reader.Read();
            }
        }

        private int ReadAttributeInt(XmlReader reader, string attributeName)
        {
            reader.MoveToAttribute(attributeName);
            return int.Parse(reader.Value);
        }

        protected override Dictionary Deserialize(IntermediateReader input, Microsoft.Xna.Framework.Content.ContentSerializerAttribute format, Dictionary existingInstance)
        {
            Dictionary dictionary = new Dictionary();
            dictionary.letters = new Dictionary.Letters();
            dictionary.letters.characters = new List<Dictionary.Letters.Character>();
            dictionary.words = new Dictionary.Words();
            dictionary.words.words = new HashSet<string>();

            ReadToNextElement(input.Xml);
            dictionary.letters.totalInstances = ReadAttributeInt(input.Xml, "TotalInstances");

            ReadToNextElement(input.Xml);

            while (input.Xml.Name == "Letter")
            {
                Dictionary.Letters.Character character = new Dictionary.Letters.Character();

                character.count = ReadAttributeInt(input.Xml, "Count");

                input.Xml.Read();
                character.character = input.Xml.Value[0];

                dictionary.letters.characters.Add(character);
                ReadToNextElement(input.Xml);
            }

            dictionary.words.count = ReadAttributeInt(input.Xml, "Count");

            for (int i = 0; i < dictionary.words.count; i++)
            {
                ReadToNextElement(input.Xml);
                input.Xml.Read();
                dictionary.words.words.Add(input.Xml.Value);
                ReadToEndElement(input.Xml);
            }

            ReadToEndElement(input.Xml);    // read to the end of words
            ReadToEndElement(input.Xml);    // read to the end of asset

            return dictionary;
        }

        protected override void Serialize(IntermediateWriter output, Dictionary value, Microsoft.Xna.Framework.Content.ContentSerializerAttribute format)
        {
            throw new NotImplementedException();
        }
    }
}
...