0

如果可能的话,我想以正确的方式做到这一点。我有如下 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< Dictionary >)将其加载到其中之一

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 文件?

谢谢!查理。

4

2 回答 2

1

这可能有助于http://blogs.msdn.com/b/shawnhar/archive/2009/03/25/automatic-xnb-serialization-in-xna-game-studio-3-1.aspx。我发现反过来检查我的 xml 数据是否正确定义很有用。实例化您的字典类设置所有字段,然后使用 XmlSerializer 将其序列化为 xml 以检查输出。

于 2010-06-30T16:15:41.743 回答
0

您需要为您的 Dictionary 类实现一个 ContentTypeSerializer。将其放入内容扩展库中,并将对内容扩展库的引用添加到您的内容项目中。将您的 Dictionary 类放入您的游戏和内容扩展项目都引用的游戏库中。

请参阅:http: //blogs.msdn.com/b/shawnhar/archive/2008/08/26/customizing-intermediateserializer-part-2.aspx

这是我写的一个快速的 ContentTypeSerializer,它将反序列化您的 Dictionary 类。它可以使用更好的错误处理。

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();
        }
    }
}
于 2010-09-16T09:53:20.017 回答