Опустить xmldeclaration в XmlWriter и реализовать IXmlSerializable

#c# #.net #xml #xml-serialization #ixmlserializable

#c# #.net #xml #xml-сериализация #ixmlserializable

Вопрос:

Я хочу создать пользовательскую сериализацию xml, внедрив IXmlSerializable. У меня есть этот тестовый класс, который реализует интерфейс IXmlSerializable:

 [Serializable]
public class Employee : IXmlSerializable
{
    public Employee()
    {
        Name = "Vyacheslav";

        Age = 23;                 
    }

    public string Name{get; set;}

    public int Age { get; set; }



    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        this.Name = reader["Name"].ToString();
        this.Age = Int32.Parse(reader["Age"].ToString());
    }

    public void WriteXml(XmlWriter writer)
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.OmitXmlDeclaration = true;
        settings.ConformanceLevel = ConformanceLevel.Fragment;

        XmlWriter newWriter = XmlWriter.Create(writer, settings);
        newWriter.WriteAttributeString("Name", this.Name);
        newWriter.WriteAttributeString("Age", this.Age.ToString());            
    }
}
  

Что я хочу сделать, так это опустить объявление xml. Для этого я создаю надлежащий экземпляр XmlWriterSettings и передаю его в качестве второго параметра для создания нового XmlWriter.
Но когда я отлаживаю этот фрагмент кода, я вижу этот newWriter.Для параметра Settings.OmitXmlDeclaration установлено значение false, а сериализованные данные содержат тег. Что я делаю не так?

Фактическая сериализация выглядит следующим образом:

         var me = new Employee();

        XmlSerializer serializer = new XmlSerializer(typeof(Employee));
        TextWriter writer = new StreamWriter(@"D:file.txt");
        serializer.Serialize(writer, me);
        writer.Close();
  

И второй вопрос: если я хочу сериализовать тип Employee, у которого есть поле ContactInfo типа cutom для сериализации, нужно ли мне также внедрять IXmlSerializable в ContactInfo?

Комментарии:

1. Обратите внимание, что вам это не нужно [Serializable] .

Ответ №1:

Параметры записи — это функция самого внешнего устройства записи; вы должны применять это к коду, который создает файл, т.е.

 using(var file = File.Create("file.txt"))
using(var writer = XmlWriter.Create(file, settings))
{
    serializer.Serialize(writer, me);
}
  

кроме того, тогда вам не нужно реализовывать IXmlSerializable . Вы не можете сделать это на внутреннем уровне — уже слишком поздно.

Например:

 using System.IO;
using System.Xml;
using System.Xml.Serialization;
public class Employee 
{
    [XmlAttribute] public string Name { get; set; }
    [XmlAttribute] public int Age { get; set; }
}
class Program
{
    static void Main()
    {
        var settings = new XmlWriterSettings();
        settings.OmitXmlDeclaration = true;
        var me = new Employee {
            Name = "Vyacheslav", Age = 23
        };
        var serializer = new XmlSerializer(typeof (Employee));
        using (var file = File.Create("file.txt"))
        using (var writer = XmlWriter.Create(file, settings))
        {
            serializer.Serialize(writer, me);
        }
    }
}
  

и если вам не нужны дополнительные пространства имен, то:

         var ns = new XmlSerializerNamespaces();
        ns.Add("", "");
        serializer.Serialize(writer, me, ns);
  

который генерирует файл:

 <Employee Name="Vyacheslav" Age="23" />