#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" />