在 C# 和 XNA 4.0 中使用 XMLReader 时出错

发布于 2024-11-30 19:13:54 字数 4192 浏览 0 评论 0原文

我正在尝试在 XNA 中为共享元素的字典编写 ContentTypeSerializer,我几乎已经完成了,但由于我对 XmlReader 类缺乏了解,在反序列化字典 xml 时出现错误。

我使用此函数来序列化字典(工作正常):

protected override void Serialize(IntermediateWriter output,
                                      SharedResourceDictionary<T, K> value,
                                      ContentSerializerAttribute format)
    {
         foreach (KeyValuePair<T, K> item in value)// foreach (T item in value)
        {
            output.Xml.WriteStartElement(itemFormat.ElementName);
            output.WriteObject(item.Key, keyFormat);
            output.WriteSharedResource(item.Value, valueFormat);
            output.Xml.WriteEndElement();
        }
    }

它会生成以下 XML: http://pastebin.com/19fEteqV< /a> (抱歉,我无法以 xml 格式将其发布到此处)

最后我尝试使用此函数进行反序列化:

protected override SharedResourceDictionary<T, K> Deserialize(IntermediateReader input,
                                                         ContentSerializerAttribute format,
                                                         SharedResourceDictionary<T, K> existingInstance)
    {
        if (existingInstance == null)
            existingInstance = new SharedResourceDictionary<T, K>();

        while (input.MoveToElement(itemFormat.ElementName))
        {

            T key;

            input.Xml.ReadToDescendant(keyFormat.ElementName);
            key = input.ReadObject<T>(keyFormat);
            input.Xml.ReadToNextSibling(valueFormat.ElementName);
            input.ReadSharedResource(
                valueFormat, 
                (K value) => existingInstance.Add(key, value));
            input.Xml.MoveToElement();


        }

        return existingInstance;
    }

问题是,当我尝试加载时出现以下异常

Microsoft.Xna.Framework.Content.Pipeline.InvalidContentException was unhandled
  Message=XML element "Resources" not found.
  Source=Microsoft.Xna.Framework.Content.Pipeline
  StackTrace:
       at Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateReader.ReadSharedResources()
       at Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateSerializer.Deserialize[T](XmlReader input, String referenceRelocationPath)
       at SerializationTest.Modes.Mode4.Update(GameTime gameTime) in D:\All\Proyects\SerializationTest\SerializationTest\SerializationTest\Modes\Mode4.cs:line 87
       at Microsoft.Xna.Framework.Game.Update(GameTime gameTime)
       at SerializationTest.Game1.Update(GameTime gameTime) in D:\All\Proyects\SerializationTest\SerializationTest\SerializationTest\Game1.cs:line 78
       at Microsoft.Xna.Framework.Game.Tick()
       at Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
       at Microsoft.Xna.Framework.GameHost.OnIdle()
       at Microsoft.Xna.Framework.WindowsGameHost.RunOneFrame()
       at Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
       at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Microsoft.Xna.Framework.WindowsGameHost.Run()
       at Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun)
       at Microsoft.Xna.Framework.Game.Run()
       at SerializationTest.Program.Main(String[] args) in D:\All\Proyects\SerializationTest\SerializationTest\SerializationTest\Program.cs:line 15
  InnerException: 

:代码可以在此处找到。不想将帖子与所有内容聚集在一起。 如果有人有任何建议,我们将不胜感激。我很确定错误是在反序列化函数中解析 xml 时出现的,但我一生都找不到它。

感谢您抽出时间。

I'm trying to write a ContentTypeSerializer in XNA for Dictionaries of shared elements, and I'm almost there but have got an error when deserializing the dictionary xml, due to my lack of understanding of the XmlReader class.

I use this function to serialize the dictionary (works fine):

protected override void Serialize(IntermediateWriter output,
                                      SharedResourceDictionary<T, K> value,
                                      ContentSerializerAttribute format)
    {
         foreach (KeyValuePair<T, K> item in value)// foreach (T item in value)
        {
            output.Xml.WriteStartElement(itemFormat.ElementName);
            output.WriteObject(item.Key, keyFormat);
            output.WriteSharedResource(item.Value, valueFormat);
            output.Xml.WriteEndElement();
        }
    }

And it generates this XML: http://pastebin.com/19fEteqV (sorry, I don't manage to post it here with xml formatting)

And finally I try to use this function to deserialize:

protected override SharedResourceDictionary<T, K> Deserialize(IntermediateReader input,
                                                         ContentSerializerAttribute format,
                                                         SharedResourceDictionary<T, K> existingInstance)
    {
        if (existingInstance == null)
            existingInstance = new SharedResourceDictionary<T, K>();

        while (input.MoveToElement(itemFormat.ElementName))
        {

            T key;

            input.Xml.ReadToDescendant(keyFormat.ElementName);
            key = input.ReadObject<T>(keyFormat);
            input.Xml.ReadToNextSibling(valueFormat.ElementName);
            input.ReadSharedResource(
                valueFormat, 
                (K value) => existingInstance.Add(key, value));
            input.Xml.MoveToElement();


        }

        return existingInstance;
    }

The problem is that when I attempt to load I get the following exception:

Microsoft.Xna.Framework.Content.Pipeline.InvalidContentException was unhandled
  Message=XML element "Resources" not found.
  Source=Microsoft.Xna.Framework.Content.Pipeline
  StackTrace:
       at Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateReader.ReadSharedResources()
       at Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate.IntermediateSerializer.Deserialize[T](XmlReader input, String referenceRelocationPath)
       at SerializationTest.Modes.Mode4.Update(GameTime gameTime) in D:\All\Proyects\SerializationTest\SerializationTest\SerializationTest\Modes\Mode4.cs:line 87
       at Microsoft.Xna.Framework.Game.Update(GameTime gameTime)
       at SerializationTest.Game1.Update(GameTime gameTime) in D:\All\Proyects\SerializationTest\SerializationTest\SerializationTest\Game1.cs:line 78
       at Microsoft.Xna.Framework.Game.Tick()
       at Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
       at Microsoft.Xna.Framework.GameHost.OnIdle()
       at Microsoft.Xna.Framework.WindowsGameHost.RunOneFrame()
       at Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
       at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Microsoft.Xna.Framework.WindowsGameHost.Run()
       at Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun)
       at Microsoft.Xna.Framework.Game.Run()
       at SerializationTest.Program.Main(String[] args) in D:\All\Proyects\SerializationTest\SerializationTest\SerializationTest\Program.cs:line 15
  InnerException: 

The complete code can be found here. Didn't want to cluster the post with all of it.
If anyone has any suggestion, it is much appreciated. I'm pretty sure the error is on parsing the xml in the deserialize function but I can't find it for the life of me.

Thank you for your time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乖乖公主 2024-12-07 19:13:54

您没有读取 Item 标记的结束元素,因此读者在读取第一个键/值对后会变得疯狂。以下是更正后的 Deserialize 函数:

    protected override SharedResourceDictionary<T, K> Deserialize(IntermediateReader input,
                                                             ContentSerializerAttribute format,
                                                             SharedResourceDictionary<T, K> existingInstance)
    {
        if (existingInstance == null)
            existingInstance = new SharedResourceDictionary<T, K>();

        while (input.MoveToElement(Itemformat.ElementName))
        {
            T key;

            input.Xml.ReadToDescendant(Keyformat.ElementName);
            key = input.ReadObject<T>(Keyformat);
            input.Xml.ReadToNextSibling(Valueformat.ElementName);
            input.ReadSharedResource<K>(Valueformat, (K value) =>
            {
                existingInstance.Add(key, value);
            });
            input.Xml.ReadEndElement();
        }

        return existingInstance;
    }
}

You weren't reading the ending element of your Item tag, so the reader was going wild after reading the first key/value pair. Here is the corrected Deserialize function:

    protected override SharedResourceDictionary<T, K> Deserialize(IntermediateReader input,
                                                             ContentSerializerAttribute format,
                                                             SharedResourceDictionary<T, K> existingInstance)
    {
        if (existingInstance == null)
            existingInstance = new SharedResourceDictionary<T, K>();

        while (input.MoveToElement(Itemformat.ElementName))
        {
            T key;

            input.Xml.ReadToDescendant(Keyformat.ElementName);
            key = input.ReadObject<T>(Keyformat);
            input.Xml.ReadToNextSibling(Valueformat.ElementName);
            input.ReadSharedResource<K>(Valueformat, (K value) =>
            {
                existingInstance.Add(key, value);
            });
            input.Xml.ReadEndElement();
        }

        return existingInstance;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文