Сериализация XML, кодирование

using System;

public class clsPerson
{
  public  string FirstName;
  public  string MI;
  public  string LastName;
}

class class1
{ 
   static void Main(string[] args)
   {
      clsPerson p=new clsPerson();
      p.FirstName = "Jeff";
      p.MI = "A";
      p.LastName = "Price";
      System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());
      x.Serialize(Console.Out, p);
      Console.WriteLine();
      Console.ReadLine();
   }
} 

взято из http://support.microsoft.com/kb/815813

1)

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());

Что делает эта линия? Что такое GetType()?

2) как получить кодировку

<?xml version="1.0" encoding="utf-8"?>
< clsPerson xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

вместо

<?xml version="1.0" encoding="IBM437"?>
 <clsPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3
 .org/2001/XMLSchema">

или вообще не включать тип кодирования?

Ответ 1

1) Функция GetType() возвращает объект Type, представляющий тип вашего объекта, в этом случае класс clsPerson. Вы также можете использовать typeof(clsPerson) и получить тот же результат. Эта строка создает объект XmlSerializer для вашего конкретного класса.

2) Если вы хотите изменить кодировку, я считаю, что есть переопределение функции Serialize(), которая позволяет вам указать это. Подробнее см. MSDN. Возможно, вам придется создать объект XmlWriter, но подробности для него также находятся на MSDN:

 XmlWriter writer = XmlWriter.Create(Console.Out, settings);

Вы также можете установить кодировку в XmlWriter, объект XmlWriterSettings имеет свойство Encoding.

Ответ 2

Если вы передаете сериализатор XmlWriter, вы можете управлять некоторыми параметрами, такими как кодирование, опустить объявление (например, для фрагмента) и т.д.

Это не должно быть окончательным руководством, а альтернативой, чтобы вы могли видеть, что происходит, и что-то, что не просто собирается консолировать в первую очередь.

Обратите внимание, что если вы создаете свой XmlWriter с помощью StringBuilder вместо MemoryStream, ваш xml проигнорирует вашу кодировку и выйдет как кодировка utf-16. Для получения дополнительной информации см. Запись в блоге запись xml с кодировкой utf8.

XmlWriterSettings xmlWriterSettings = new XmlWriterSettings 
{ 
    Indent = true, 
    OmitXmlDeclaration = false, 
    Encoding = Encoding.UTF8 
};

using (MemoryStream memoryStream = new MemoryStream() )
using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
{   
    var x = new System.Xml.Serialization.XmlSerializer(p.GetType());
    x.Serialize(xmlWriter, p);

    // we just output back to the console for this demo.
    memoryStream.Position = 0; // rewind the stream before reading back.
    using( StreamReader sr = new StreamReader(memoryStream))
    {
        Console.WriteLine(sr.ReadToEnd());
    } // note memory stream disposed by StreamReaders Dispose()
}

Ответ 3

1) Это создает XmlSerializer для класса clsPerson.

2) кодирование - это IBM437, потому что это форма для потока Console.Out.

PS: венгерская нотация не является предпочтительной в С#; просто назовите вас классом Person.

Ответ 4

Я принял решение, предлагаемое @robert-paulson здесь для аналогичной вещи, которую я пытался сделать, и получить строку XmlSchema. По умолчанию он будет возвращаться как utf-16. Однако, как упоминалось, решение здесь страдает от ошибки чтения с потоком. Поэтому я стараюсь размещать рефактор в качестве метода расширения с помощью tweek, упомянутого @Liam, для перемещения блока использования.

    public static string ToXmlString(this XmlSchema xsd)
    {
        var xmlWriterSettings = new XmlWriterSettings
        {
            Indent = true,
            OmitXmlDeclaration = false,
            Encoding = Encoding.UTF8
        };

        using (var memoryStream = new MemoryStream())
        {
            using (var xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
            {
                xsd.Write(xmlWriter);
            }

            memoryStream.Position = 0; 
            using (var sr = new StreamReader(memoryStream))
            {
                return sr.ReadToEnd();
            }
        }
    }