首页 > 解决方案 > 使用 ASP.NET 中的实例值自定义命名 XML 标记

问题描述

我正在研究这个 ASP.NET Api,其中数据是通过 GET 请求获取的,格式为 XML。

现在,所有 xml 节点都是使用代码元素(类名、属性名等)生成的。如果我愿意,我可以使用诸如 [XmlType(TypeName = "DesiredName")] 之类的属性来更改这些节点名称,但它仍然是与我在代码中使用的名称的一对一映射。

我有一个特定的对象类型,我想使用实际的运行时值来格式化,而不是编译时符号。

以下是课程:

public class RootClass
{
    public string ID { get; set; }
    public List<Property> Properties { get; set; }
}

public class Property
{
    public string PropertyType { get; set; }
    // Other Fields
}

假设我有几个属性,它们的属性类型为“Type1”、“Type2”、“Type3”

我想要的 Xml 如下所示:

<RootClass>
    <ID>23</ID>
    <Properties>
        <Type1>
            <Property>
                // Other Fields
            </Property>
            <Property>
                // Other Fields
            </Property>
        </Type1>
        <Type2>
            <Property>
                // Other Fields
            </Property>
        </Type2>
    </Properties>
</RootType>

如您所见,其中一个节点的命名取决于值,而不是模式。当从模型映射到 DTO 时,我可以轻松地通过代码进行分组,并且我可以完全控制 DTO 的类,因此我可以根据需要更改它们以获得预期的 XML。

首先,这可能吗?

如果是,我的类结构(和属性)应该是什么样子才能实现这一点(列表字典?自定义集合?)

如果不是,我还有哪些其他选择才能实现尽可能接近此的目标?

标签: c#asp.netxmldto

解决方案


尝试 Xml Linq:

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            RootClass root = new RootClass()
            {
                ID = "23",
                Properties = new List<Property>() {
                    new Property() { PropertyType = "Type1", Properties = new List<string>() { "A", "B", "C"} },
                    new Property() { PropertyType = "Type2", Properties = new List<string>() { "A", "B", "C"} }
                }
            };

            XElement rootClass = new XElement("RootClass", new object[] {
                new XElement("ID", root.ID),
                new XElement("Properties")
            });

            XElement properties = rootClass.Element("Properties");
            int count = 1;
            foreach (Property property in root.Properties)
            {
                XElement type = new XElement(property.PropertyType);
                properties.Add(type);
                foreach (string p in property.Properties)
                {
                    XElement strProperty = new XElement("Property", new object[] {
                        new XElement(p, count++)
                    });
                    type.Add(strProperty);
                }
            }

            rootClass.Save(FILENAME);
        }
    }
    public class RootClass
    {
        public string ID { get; set; }
        public List<Property> Properties { get; set; }
    }

    public class Property
    {
        public string PropertyType { get; set; }
        public List<string> Properties { get; set; }
    }
}

推荐阅读