XML序列化,编码

18
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">

是不是可以完全不包含编码类型呢?

4个回答

63
如果您向序列化器传递XmlWriter,您可以控制一些参数,如编码、是否省略声明(例如用于片段)等。
这并不是一个明确的指南,而是一个替代方案,让您看到正在发生的事情,并且不仅仅是在控制台上输出。
请注意,如果您使用StringBuilder创建XmlWriter而不是MemoryStream,则您的xml将忽略您的编码并以utf-16编码输出。有关更多信息,请参阅博客文章使用utf8编码编写xml
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()
}

6
在这个例子中,StreamReader将关闭MemoryStream。然后,使用XmlWriter的Dispose将尝试访问已关闭的流。请参阅https://dev59.com/yVXTa4cB1Zd3GeqP4LRs#8833066获取替代的using结构方式。 - Liam
哎呀。谈论隐藏的复杂性。 - crush

14

1) GetType()函数返回表示对象类型的Type对象,在这里是clsPerson类。您也可以使用typeof(clsPerson)获得相同的结果。这行代码为您特定的类创建了一个XmlSerializer对象。

2) 如果您想更改编码,我相信Serialize()函数有一个重载,允许您指定编码方式。请参阅MSDN获取详细信息。但是,您可能需要创建一个XmlWriter对象来使用它,相关的详情也在MSDN上:

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

您还可以在XmlWriter中设置编码,XmlWriterSettings对象具有Encoding属性。


3

我采用了@robert-paulson在这里提供的解决方案来获取XmlSchema字符串,但默认情况下它会以utf-16返回。但是,正如在这里提到的,该解决方案遭受了“流关闭读取错误”的困扰。因此,我利用@Liam提到的小技巧,将其重构为扩展方法,并移动了using块。

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

2

1) 这将为类clsPerson创建一个XmlSerializer。

2) 编码为IBM437,因为这是Console.Out流的形式。

PS:在C#中不推荐使用匈牙利命名法;只需将类命名为Person即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接