【问题标题】:Deserialize rooted XML elements into an array将根 XML 元素反序列化为数组
【发布时间】:2015-04-25 01:35:52
【问题描述】:

我需要将 XML 中的多个字段保存到不同的数组中。 这就是我的 XML 的样子:

<Content>
    <Colours>
        <Colour name="Strong Red">
                <R>255</R>      
                <G>0</G>
                <B>0</B>
                <A>255</A> 
        </Colour>
    </Colours>
    <Textures>
         <Texture name="Character01">
             <Path>Path/Folder</Path>
         </Texture>
    </Textures>
</Content>

&lt;Colours&gt; 是我的根并且我只将颜色添加到一个数组中时,现在一切正常。

现在我想通过同一个 XML 文件添加纹理,然后再添加更多,从而将根移到 &lt;Content&gt;

这就是我的 ColourLoader 类的样子,只有颜色,&lt;Colour&gt; 是我的 XML 的根:

[Serializable()]
[XmlRoot("Colours")]
public class ColourLoader
{
    [XmlElement("Colour")]
    public CustomColour[] Colours;

    public static ColourLoader Load(string path)
    {
        var serializer = new XmlSerializer(typeof(ColourLoader));
        using (var stream = new FileStream(path, FileMode.Open))
        {
            return serializer.Deserialize(stream) as ColourLoader;
        }        
    }
}

我的 CustomColour 类工作正常,它使用 [XmlElement("R")] 等从 XML 读取值。只是我不知道如何从嵌套的 XML 中读取元素。 我必须以某种方式跳过&lt;Content&gt; 并从&lt;Colours&gt; 添加颜色作为root 并为&lt;Textures&gt; 等做同样的事情。

我不想创建多个 XML 文件,因为我想将所有内容管理到一个位置,并且只加载一次 XML 文件。

【问题讨论】:

  • 创建一个Content 类并向其添加属性Colours
  • 您是否打算从同一个 XML 文档中加载单独的 *Loader 类(ColourLoaderTextureLoader 等)?
  • 目前就是这样设置的,是的。我宁愿将内容加载分组到一个类中,但这是我第一次使用 Xml。现在的设置方式可以说是各种尝试的结果。
  • RGBA 已经成熟,可以成为 Xml 属性而不是元素。

标签: c# arrays xml object serialization


【解决方案1】:

我想这就是你所追求的。我还包含了一个序列化对象的方法。我发现这对诊断 XML 序列化的特殊问题非常有帮助......

如果这解决了您的问题,请投票作为答案。

    [Serializable()]
    [XmlRoot("Content")]
    public class Content
    {
        [XmlArray("Colours")]
        [XmlArrayItem("Colour")]
        public CustomColour[] Colours { get; set; }

        [XmlArray("Textures")]
        [XmlArrayItem("Texture")]
        public CustomTexture[] Textures { get; set; }
    }

    [Serializable()]
    [XmlRoot("Colour")]
    public class CustomColour
    {
        [XmlAttribute("name")]
        public string Name { get; set; }

        [XmlElement("R")]
        public int R { get; set; }

        [XmlElement("G")]
        public int G { get; set; }

        [XmlElement("B")]
        public int B { get; set; }

        [XmlElement("A")]
        public int A { get; set; }
    }

    [Serializable()]
    [XmlRoot("Texture")]
    public class CustomTexture
    {
        [XmlAttribute("name")]
        public string Name { get; set; }

        [XmlElement("Path")]
        public string Path { get; set; }
    }

    public static class ContentLoader
    {
        public static Content Load(TextReader textReader)
        {
            var serializer = new XmlSerializer(typeof(Content));
            var ret = serializer.Deserialize(textReader) as Content;
            return ret;
        }

        public static void Save(TextWriter textWriter, Content content)
        {
            var serializer = new XmlSerializer(typeof(Content));
            serializer.Serialize(textWriter, content);
        }
    }

    public static void XmlSerializing()
    {
        var xml = @"<?xml version=""1.0"" encoding=""utf-16""?>
                    <Content xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
                        <Colours>
                            <Colour name=""Strong Red"">
                                    <R>255</R>      
                                    <G>0</G>
                                    <B>0</B>
                                    <A>255</A> 
                            </Colour>
                        </Colours>
                        <Textures>
                             <Texture name=""Character01"">
                                 <Path>Path/Folder</Path>
                             </Texture>
                        </Textures>
                    </Content>";
        var reader = new StringReader(xml);
        var content = ContentLoader.Load(reader);

        Console.WriteLine("Deserialized version:");
        Console.WriteLine("  Colours");
        foreach (var colour in content.Colours)
        {
            Console.WriteLine("    R: {0}, G: {1}, B: {2}, A: {3}", colour.R, colour.G, colour.B, colour.A);
        }

        Console.WriteLine("  Textures");
        foreach (var texture in content.Textures)
        {
            Console.WriteLine("    Path: {0}", texture.Path);
        }

        var contentObj = new Content()
                            {
                                Colours = new[] { new CustomColour() { Name = "StrongRed", R = 255, G = 0, B = 0, A = 255 } },
                                Textures = new[] { new CustomTexture() { Name = "Character01", Path = "Path/Folder" } }
                            };

        Console.WriteLine(string.Empty);
        Console.WriteLine("Serialized version:");
        var writer = new StringWriter();
        ContentLoader.Save(writer, contentObj);
        Console.WriteLine(writer);
    }

【讨论】:

  • 它运行良好,非常感谢。我现在可以根据需要添加任意数量的自定义内容元素,并且所有内容都可以完美地加载到游戏中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-02
  • 2015-04-13
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多