XmlAttributes Access Defines the added attributes in IXmlSerializable methods

How do I access XmlAttributesapplied to fields in an object IXmlSerializableusing XmlAttributesOverrides?

Example IXmlSerializable object:

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

Typical override creation:

        // 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 ...

Created output:

<?xml version="1.0" encoding="utf-8"?><Person><Name1>First</Name1><Name2>Second</Name2></Person>

I need to use IXmlSerializableto overcome inheritance problems from "SomeBaseClass".

The problem is that it GetCustomArributesdoes not return any attributes added to the collection XmlAttributeOverrides, or am I doing it wrong !?

It is also likely that it is GetCustomAttributesnot SUPPOSED to return such added attributes, or that I should not use XmlAttributeOverridesin the class IXmlSerializable.

So ... any ideas or alternatives. Thanks for taking the time.

+5
2

.

, XmlSerializer , IXmlSerializable. XML Overrides -. XML ; .

, IXmlSerializable, . XML Override, serializer. Person serializer ( ):

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

, serializer, , , . :

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

XmlWriter FieldInfo, . (Person in example) . 2 : Name1 Name1. , , bool (bool DoNotSerializeName1), , Name1. , -...

:

using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace XmlCustomSerializer
{
    public class Person : 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)
        {
            // ....
        }

        private static FieldInfo[] _cachedFields = null;
        public void WriteXml(XmlWriter writer)
        {
            var customWriter = writer as XmlCustomWriter;
            if (customWriter == null)
                throw new ArgumentException("writer");

            if (_cachedFields == null)
            {
                _cachedFields = typeof(Person).GetFields();
            }

            foreach (FieldInfo finf in customWriter.FieldsToSerialize)
            {
                if (_cachedFields.Contains(finf))
                {
                    writer.WriteElementString(finf.Name, (string)finf.GetValue(this));
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var person = new Person
            {
                Name1 = "Some",
                Name2 = "Person",
                Name3 = "Name"
            };

            var settings = new XmlWriterSettings { Indent = true, Encoding = Encoding.ASCII };
            var allFields = typeof(Person).GetFields();

            XmlSerializer xSer = new XmlSerializer(typeof(Person));

            using (var stream = new MemoryStream())
            {
                var xmlCustomWriter = new XmlCustomWriter(
                    XmlWriter.Create(new StreamWriter(stream), settings));

                //serialize all fields
                xmlCustomWriter.FieldsToSerialize = allFields;

                xSer.Serialize(xmlCustomWriter, person);

                stream.Seek(0, SeekOrigin.Begin);
                Console.WriteLine(new StreamReader(stream).ReadToEnd());
            }

            using (var stream = new MemoryStream())
            {
                var xmlCustomWriter = new XmlCustomWriter(
                    XmlWriter.Create(new StreamWriter(stream), settings));

                //serialize 2 fields
                xmlCustomWriter.FieldsToSerialize = allFields.Skip(1);

                xSer.Serialize(xmlCustomWriter, person);

                stream.Seek(0, SeekOrigin.Begin);
                Console.WriteLine(new StreamReader(stream).ReadToEnd());
            }

            Console.Read();
        }
    }
}

XmlCustomWriter:

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

namespace XmlCustomSerializer
{
    public class XmlCustomWriter : XmlWriter
    {
        private readonly XmlWriter _innerWriter;

        public XmlCustomWriter(XmlWriter innerWriter)
        {
            if (innerWriter == null)
                throw new ArgumentNullException("innerWriter");
            _innerWriter = innerWriter;
            FieldsToSerialize = Enumerable.Empty<FieldInfo>();
        }

        public IEnumerable<FieldInfo> FieldsToSerialize { get; set; }

        #region Implement XmlWriter
        public override void Flush()
        {
            _innerWriter.Flush();
        }

        public override string LookupPrefix(string ns)
        {
            return _innerWriter.LookupPrefix(ns);
        }

        public override void WriteBase64(byte[] buffer, int index, int count)
        {
            _innerWriter.WriteBase64(buffer, index, count);
        }

        public override void WriteCData(string text)
        {
            _innerWriter.WriteCData(text);
        }

        public override void WriteCharEntity(char ch)
        {
            _innerWriter.WriteCharEntity(ch);
        }

        public override void WriteChars(char[] buffer, int index, int count)
        {
            _innerWriter.WriteChars(buffer, index, count);
        }

        public override void WriteComment(string text)
        {
            _innerWriter.WriteComment(text);
        }

        public override void WriteDocType(string name, string pubid, string sysid, string subset)
        {
            _innerWriter.WriteDocType(name, pubid, sysid, subset);
        }

        public override void WriteEndAttribute()
        {
            _innerWriter.WriteEndAttribute();
        }

        public override void WriteEndDocument()
        {
            _innerWriter.WriteEndDocument();
        }

        public override void WriteEndElement()
        {
            _innerWriter.WriteEndElement();
        }

        public override void WriteEntityRef(string name)
        {
            _innerWriter.WriteEntityRef(name);
        }

        public override void WriteFullEndElement()
        {
            _innerWriter.WriteFullEndElement();
        }

        public override void WriteProcessingInstruction(string name, string text)
        {
            _innerWriter.WriteProcessingInstruction(name, text);
        }

        public override void WriteRaw(string data)
        {
            _innerWriter.WriteRaw(data);
        }

        public override void WriteRaw(char[] buffer, int index, int count)
        {
            _innerWriter.WriteRaw(buffer, index, count);
        }

        public override void WriteStartAttribute(string prefix, string localName, string ns)
        {
            _innerWriter.WriteStartAttribute(prefix, localName, ns);
        }

        public override void WriteStartDocument(bool standalone)
        {
            _innerWriter.WriteStartDocument(standalone);
        }

        public override void WriteStartDocument()
        {
            _innerWriter.WriteStartDocument();
        }

        public override void WriteStartElement(string prefix, string localName, string ns)
        {
            _innerWriter.WriteStartElement(prefix, localName, ns);
        }

        public override WriteState WriteState
        {
            get { return _innerWriter.WriteState; }
        }

        public override void WriteString(string text)
        {
            _innerWriter.WriteString(text);
        }

        public override void WriteSurrogateCharEntity(char lowChar, char highChar)
        {
            _innerWriter.WriteSurrogateCharEntity(lowChar, highChar);
        }

        public override void WriteWhitespace(string ws)
        {
            _innerWriter.WriteWhitespace(ws);
        }
        #endregion Implement XmlWriter
    }
}
0

All Articles