是否可以将自定义结构序列化为xml属性?

Joh*_*son 5 c# struct xml-serialization xml-attribute

是否可以将自定义结构序列化为xml属性?

示例代码:

public class Dummy<T>
{
    private Dummy() { }
    public Dummy(T item1)
    {
        Item1 = item1;
        Item2 = item1;
    }

    public T Item1 { get; set; }
    [XmlAttribute]
    public T Item2 { get; set; }
}

public struct Meh
{
    public int Prop { get; set; }
}

[Test]
public void XmlMehTest()
{
    var meh = new Meh{Prop = 1};
    var dummy = new Dummy<Meh>(meh);
    using (var writer = new StringWriter())
    {
        var serializer = new XmlSerializer(dummy.GetType());
        // System.InvalidOperationException : Cannot serialize member 'Meh2' of type Meh. 
        // XmlAttribute/XmlText cannot be used to encode complex types.
        serializer.Serialize(writer, dummy);
        Console.Write(writer.ToString());
    }
}

[Test]
public void XmlDateTimeTest()
{
    var dummy = new Dummy<DateTime>(DateTime.Now);
    using (var writer = new StringWriter())
    {
        var serializer = new XmlSerializer(dummy.GetType());
        serializer.Serialize(writer, dummy);
        Console.Write(writer.ToString());
    }
}
Run Code Online (Sandbox Code Playgroud)

请忽略结构是可变的,就像紧凑的样本一样.

这确实是但我仍然很好奇:)

Sel*_*enç 4

文档

您只能将 XmlAttributeAttribute 分配给返回值(或值数组)的公共字段或公共属性,这些值可以映射到 XML 架构定义语言 (XSD) 简单类型(包括从 XSD 派生的所有内置数据类型)之一。任何 SimpleType 类型)。可能的类型包括任何可以映射到 XSD 简单类型的类型,包括 Guid、Char 和枚举。

因此,要做到这一点,我们应该能够为 XSD 创建我们自己的类型定义,我想我们可以做到这一点。因为此文档包含有关它的完整解释。但我们不能做的是,我们不能包含我们的定义到此列表。最初XML Serializer 使用这些类型来确定类型的 XSD 类型定义。您可以使用此属性,DateTime因为它是使用此方法创建的定义并存储在 HashTable 中:

AddPrimitive(typeof(DateTime), "dateTime", "DateTime", 
             TypeFlags.XmlEncodingNotRequired | 
             TypeFlags.HasCustomFormatter | 
             TypeFlags.CanBeElementValue | **TypeFlags.CanBeAttributeValue**);
Run Code Online (Sandbox Code Playgroud)

AddPrimitive方法:

private static void AddPrimitive(Type type, string dataTypeName, string formatterName, TypeFlags flags)
    {
        XmlSchemaSimpleType dataType = new XmlSchemaSimpleType {
            Name = dataTypeName
        };
        TypeDesc desc = new TypeDesc(type, true, dataType, formatterName, flags);
        if (primitiveTypes[type] == null)
        {
            primitiveTypes.Add(type, desc);
        }
        primitiveDataTypes.Add(dataType, desc);
        primitiveNames.Add(dataTypeName, "http://www.w3.org/2001/XMLSchema", desc);
    }
Run Code Online (Sandbox Code Playgroud)

这个定义是XmlReflectionImporter这样调用的(根据 StackTrace 生成异常):

this.GetTypeDesc(name, ns, TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue | TypeFlags.CanBeAttributeValue);
Run Code Online (Sandbox Code Playgroud)

我想最重要的事情在这里TypeFlags.CanBeAttributeValue,我认为它指定了这种类型可以是属性值。因此,也许我们可以将自定义结构序列化为 anXmlAttirube但我们不能用标准来做到这一点XmlSerializer。因为正如我所说,它正在使用这个列表找出 XSD 类型定义。它是一个初始列表,不可能向该列表添加新元素。

PS您可能想看看这里http://msdn.microsoft.com/en-us/library/8w07bk3h(v=vs.80).aspx