加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 05:41:41 所属栏目:百科 来源:网络整理
导读:是否可以将自定义结构序列化为xml属性? 示例代码: public class DummyT{ private Dummy() { } public Dummy(T item1) { Item1 = item1; Item2 = item1; } public T Item1 { get; set; } [XmlAttribute] public T Item2 { get; set; }}public struct Meh{ p
是否可以将自定义结构序列化为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());
    }
}

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

这真是一个first-world-developer-problem,但我仍然很好奇:)

解决方法

documentation说:

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

所以要做到这一点,我们应该能够为XSD创建我们自己的类型定义,我想我们可以做到这一点.因为这个documentation包含了它的完整解释.但是我们不能做的是,我们不能包含我们的定义到目前为止,XML Serializer使用这些类型来确定类型的XSD类型定义.您可以将此属性与DateTime一起使用,因为它使用此方法创建定义并存储在HashTable中:

AddPrimitive(typeof(DateTime),"dateTime","DateTime",TypeFlags.XmlEncodingNotRequired | 
             TypeFlags.HasCustomFormatter | 
             TypeFlags.CanBeElementValue | **TypeFlags.CanBeAttributeValue**);

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);
    }

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

this.GetTypeDesc(name,ns,TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue | TypeFlags.CanBeAttributeValue);

我想最重要的是TypeFlags.CanBeAttributeValue,我认为它指定这种类型可以是attibute值.因此我们可以将自定义结构序列化为XmlAttirube但是我们不能用标准XmlSerializer来做.因为我说它使用this列表来确定XSD类型定义.它是一个初始列表,并且不可能在该列表中添加新元素.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读