【问题标题】:How to serialize XML array/list as sequentially named elements如何将 XML 数组/列表序列化为按顺序命名的元素
【发布时间】:2020-05-18 15:39:02
【问题描述】:

我需要帮助在 C#/.net 中序列化 XML。

在 C# 中给出类似的东西:

public class Action {
    public string Name;
    public string Type;
}

public class TestObject {
    public List<Action> Actions;
}

我想将动作列表序列化为元素,每个元素都有一个唯一的名称:

<TestObject>
    <Action0>
        <Name>A</Name>
        <Type>Dog</Name>
    </Action0>
    <Action1>...</Action1>
    <Action2>...</Action2>
    ...
</TestObject>

我一直在研究在自定义 List 对象上使用 IXmlSerializable 来替换 TestObject。但我不确定如何继续。

这是在正确的轨道上吗?

public class ActionCollection<T> : List<T>, IXmlSerializable ...

public class TestObject : ActionCollection<Action> { ...

想到的另一种可能性是 - 使用可以添加数字的 C# 代码自定义每个 Action 的序列化以覆盖元素名称的某种方式?

【问题讨论】:

  • 为什么?这看起来像xy problem。当 Action 元素存储在列表中时,它们以不同方式命名的动机是什么?
  • 好问题!这是所需的导出格式。我没有定义它也不能改变它——只需要产生预期的输出。我可以更改存储它的 C# 代码 - 但输出必须具有那些“顺序”名称。

标签: c# xml list xml-serialization


【解决方案1】:

使用 Xml Linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            TestObject tests = new TestObject() {
                Actions = new List<Action>() {
                    new Action() { Name = "A", Type = "Dog"},
                    new Action() { Name = "C", Type = "Cat"},
                    new Action() { Name = "E", Type = "Elephant"}
                    }
            };

            string root = "<TestObject></TestObject>";

            XDocument doc = XDocument.Parse(root);
            XElement testObject = doc.Root;

            int index = 0;
            foreach (Action action in tests.Actions)
            {
                XElement newAction = new XElement("Action" + index.ToString(), new object[] {
                    new XElement("Name", action.Name),
                    new XElement("Type", action.Type)
                });
                testObject.Add(newAction);
                index++;
            }

            doc.Save(FILENAME);

        }
    }
    public class Action
    {
        public string Name;
        public string Type;
    }

    public class TestObject
    {
        public List<Action> Actions;
    }
}

使用自定义 Xml 序列化程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Xml.Schema;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            TestObject tests = new TestObject() {
                Actions = new List<Action>() {
                    new Action() { Name = "A", Type = "Dog"},
                    new Action() { Name = "C", Type = "Cat"},
                    new Action() { Name = "E", Type = "Elephant"}
                    }
            };

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            XmlWriter writer = XmlWriter.Create(FILENAME,settings);

            XmlSerializer serializer = new XmlSerializer(typeof(TestObject));
            serializer.Serialize(writer, tests);

        }
    }
    public class Action
    {
        public string Name;
        public string Type;
    }

    public class TestObject : IXmlSerializable
    {
        public List<Action> Actions;

        public void WriteXml(XmlWriter writer)
        {
            List<XElement> testObjects = new List<XElement>();

            int index = 0;
            foreach (Action action in Actions)
            {
                XElement newAction = new XElement("Action" + index.ToString(), new object[] {
                    new XElement("Name", action.Name),
                    new XElement("Type", action.Type)
                });
                testObjects.Add(newAction);
                index++;
            }
            string obj = string.Join("", testObjects.Select(x => x.ToString()));
            writer.WriteRaw("\n" + obj + "\n");

        }
        public void ReadXml(XmlReader reader)
        {

        }

        public XmlSchema GetSchema()
        {
            return (null);
        }
    }
}

【讨论】:

  • 我喜欢这种方法,但它需要重建整个 XML 树(我忽略了每个“Action”都是一个包含嵌套子对象的相当大的对象)。
  • 我创建了一个自定义序列化程序类。见上面的修改。
  • 谢谢你,@jdweng。您的 IXmlSerializable 简单示例非常完美!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
  • 1970-01-01
  • 2015-04-13
  • 1970-01-01
相关资源
最近更新 更多