2010-06-30 81 views
0

我想尽可能以正确的方式做到这一点。我有XML数据如下:需要帮助将XML数据加载到XNA 4.0项目中

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

谢谢! 查理。

回答

1

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

+0

谢谢,这很有趣,但我需要能够以可能不完全匹配对象的格式处理XML数据。看起来我需要使用ContentReader/Writer模式,但是这仍然存在于4.0中吗?似乎文件正在迎头赶上。 – 2010-07-01 07:05:22

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