访问XmlAttributesOverrides在IXmlSerializable方法中添加了属性

Mal*_*c B 5 c# xml-serialization

如何使用?访问XmlAttributes应用于IXmlSerializable对象中的字段XmlAttributesOverrides

示例IXmlSerializable对象:

    public class Person : SomeBaseClass, IXmlSerializable
{
    public string Name1;

    public string Name2;

    [XmlIgnore]
    public string Name3;

    public Person()
    {
    }

    public Person(string first, string second, string third)
    {
        Name1 = first;
        Name2 = second;
        Name3 = third;
    }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        // ....
    }

    public void WriteXml(XmlWriter writer)
    {
        FieldInfo[] finfo = this.GetType().GetFields();

        foreach (FieldInfo finf in finfo)
        {
            FieldAttributes attr = finf.Attributes;
            object[] atts = finf.GetCustomAttributes(true);

            if (atts.Length == 0)
            {
                // handle field with no attributes ... should be just Name1
                // but also get Name2 since XmlAttributOverrides' XmlIgnore is not
                // included with GetCustomAttributes results.
                writer.WriteElementString(finf.Name, (string)finf.GetValue(this));
            }
            else
            {
                // handle field with attributes ... should be Name2 and Name3
                // but only get Name3 via [XmlIgnore] compiler generated attribute
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

典型覆盖创建:

        // parent app ...

    public XmlSerializer CreateOverrider()
    {
        XmlAttributeOverrides xOver = new XmlAttributeOverrides();
        XmlAttributes attrs = new XmlAttributes();

        attrs.XmlIgnore = true;
        xOver.Add(typeof(Person), "name2", attrs);

        XmlSerializer xSer = new XmlSerializer(typeof(Person), xOver);
        return xSer;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        // Custom XmlSerialize
        Person pson = new Person("First", "Second", "Third");

        XmlSerializer serializer = CreateOverrider();
        TextWriter writer = new StreamWriter("PersonOverride.xml");

        serializer.Serialize(writer, pson);
        writer.Close();
    }

    // etc ...
Run Code Online (Sandbox Code Playgroud)

创建输出:

<?xml version="1.0" encoding="utf-8"?><Person><Name1>First</Name1><Name2>Second</Name2></Person>
Run Code Online (Sandbox Code Playgroud)

我需要用来IXmlSerializable克服'SomeBaseClass'中的继承问题.

问题是GetCustomArributes不会返回添加到XmlAttributeOverrides集合中的任何属性- 或者我做错了!

它也可能GetCustomAttributes不支持返回这些添加的属性,或者我不应该XmlAttributeOverridesIXmlSerializable课堂上使用它.

所以...任何想法或替代品.感谢您抽出宝贵的时间.

Nic*_*ley 0

没有办法做到这一点。

原因是因为XmlSerializer当给定的对象不是IXmlSerializable. 这些 XML 覆盖属性将用于以不同的方式编译这些类。XML 覆盖属性在序列化或反序列化期间不适用于运行时;这就是为什么它们无法访问。

继承的类IXmlSerializable不会生成序列化器类。如果您想使用 XML 覆盖属性,那么您将不必覆盖序列化器类编译器。使用此实现来Person代替,让它根据给定的覆盖为​​您生成序列化器类(也将运行得快很多倍):

public class Person : SomeBaseClass
{
    public string Name1;

    public string Name2;

    [XmlIgnore]
    public string Name3;

    public Person()
    {
    }

    public Person(string first, string second, string third)
    {
        Name1 = first;
        Name2 = second;
        Name3 = third;
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,也欢迎您编写自己的序列化器类编译器,但这比这里适合的内容要复杂一些。但实现应该是这样的:

public static Type GeneratePersonSerializer(XmlAttributeOverrides overrides) {
    //here compile a class to generate a Type inheriting from IXmlSerializable
    //the serializer logic in this class should be generated by taking into
    //account the given XmlAttributeOverrides
    //the type returned should be the Type passed into new XmlSerializer(Type type)
}
Run Code Online (Sandbox Code Playgroud)