XML 序列化 【译】

原文连接:http://www.diranieh.com/NETSerialization/XMLSerialization.htm

 

总结:

  • 介绍
  • XML 序列化示例
  • XML Schema 定义文档
  • 通过 Attributes来控制XML 序列化
  • 重写XML 序列化
  • XML Namespace
  • XML 序列化和XML Web Service

 

介绍

序列化是指把对象转化为可以持续存续或者跨流程/机器传输的过程。它的方向过程就是反序列化,就是把把序列化以后的文件转换为原始的对象。.NET 提供了两种序列化的技术:二进制和XML.

 

XML 序列化

XML 序列化可以序列化一个类的公有成员和属性 或者参数,返回XML 数据流。XML 序列化不会序列化 方法,索引,私有成员 或者只读属性(除了只读集合)。因为XML是一个公开标准,XML 数据流可以被任何平台的应用传输。例如: ASP.NET Web Service 用XML 序列化创建XML 数据流 从而通过网络来传输数据。相反的,反序列化用这种数据流来构建对象。

不相二进制序列化,XML 数列化不会保存类型,换句话说,它不会包含数据类型。比如:在公司命名空间里有一个员工对象,这个不能保证反序列化的对象有相同的类型。

用System.Xml.Serialization.Xmlserializer 来执行XML 序列化和反序列化。最重要的方法是Serialize 和 Deserialize。

创建类的时候,你可以直接用C#或者其他.NET语言代码来写一个类,或者用XML Schema Definition tool(xsd.exe)根据现有的XSD来生成类。 当一个来自XSD的类序列化了,把生成的XML 依附到XML Schema。你还可以选择用.NET Framework中的其他类 比如 XmlReader和XmlWriter, 这两个类可以用来解析任何XML 数据流。相反的,当你想要XML 数据流满足XML Schema 你就可以用XmlSerializer。

用XmlSerializer生成xml数据流的时候 你可以设置XML的命名空间,元素名,属性名.....XmlSerializer 类可以更进一步的数列化对象 生成 编码的SOAP Xml 数据流。需要注意的是,XmlSerializer 类可以生成SOAP消息和传到XML Web Service。

 

可序列化的项目:

以下的几点是可以被XmlSerializer序列化的:

  • 公有 可读/可写的属性
  • 公有成员
  • 继承了ICollection 或 IEnumerable的类
  • XmlElement 对象
  • XmlNode 对象
  • DataSet 对象

用XML 序列化的优势

用XmlSerialzer有比较完整的控制劝, 比如:

  • 可以自定义成员或属性是作为元素还是属性
  • 可以自定义XML的命名空间
  • 假如成员/属性的名字不合适,可以自定义元素或者属性的名字

XML 序列化注意事项

以下是需要注意的地方:

  • 不包含类型区别和assembly信息,如果要区分类别用二进制序列化
  • 只有公有的属性和成员可以被序列化,需要序列化非公有数据请用二进制序列化
  • 如果需要序列化一个类,那么这个类一定要有默认构造函数
  • 方法不能被序列化
  • XmlSerialzer可以序列化继承ICollection或者IEnumerable的类

例子

以下的例子展示额怎么序列化一个简单的类,需要注意的是类必须要有默认构造函数:

namespace XMLSerialization
{
    [Serializable()]
    public class MyBasicClass
    {
        public string strPublic;
        public MyBasicClass( )
        {
            strPublic = "hello";
        }
    }
}

 

// Serialization / Deserialization code
uisng System.Xml.Serialization;
...

private void btnXMLSerialization_Click(object sender, System.EventArgs e)
{
    XMLSerializeMyBasicCObject();
    XMLDeSerializeMyBasicCObject(); 

}

private void XMLSerializeMyBasicCObject()
{
    // Create a serializable instnace
    XMLSerialization.MyBasicClass ob = new XMLSerialization.MyBasicClass();

    // Initialize a storage medium to hold the serialized object
    Stream stream = new FileStream( "BasicXMLSerializa.xml", FileMode.Create, FileAccess.Write, FileShare.Write);

    // Serialize an object into the storage medium referenced by 'stream' object.
    XmlSerializer xmlserializer = new XmlSerializer( typeof(XMLSerialization.MyBasicClass) );
    xmlserializer.Serialize( stream, ob );

    // Cleanup
    stream.Close();
}

private void XMLDeSerializeMyBasicCObject()
{
    // Read the file back into a stream
    Stream stream = new FileStream( "BasicXMLSerializa.xml", FileMode.Open, FileAccess.Read, FileShare.Read);

    // Now create a binary formatter
    XmlSerializer xmlserializer = new XmlSerializer( typeof(XMLSerialization.MyBasicClass) );

    // Deserialize the object and use it
    XMLSerialization.MyBasicClass ob = (XMLSerialization.MyBasicClass)xmlserializer.Deserialize( stream );
    Trace.WriteLine( ob.strPublic );

    // Cleanup
    stream.Close();
}

结果如下:

<?xml version="1.0"?>
<MyBasicClass xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <strPublic>hello</strPublic>
</MyBasicClass>

 

DataSet 序列化

以下展示了怎么序列化DataSet:

private void btnDataSet_Click(object sender, System.EventArgs e)
{
    // Construct a DataSet
    System.Data.DataSet ds = new DataSet( "MyDataSet" );
    System.Data.DataTable dt = new DataTable( "MyDataTable" );
    System.Data.DataColumn dc1 = new DataColumn( "ID", typeof (int) );
    System.Data.DataColumn dc2 = new DataColumn( "Name", typeof (string) );

    dt.Columns.Add( dc1 );
    dt.Columns.Add( dc2 );
    ds.Tables.Add( dt );

    // Add some rows
    for (int i = 0; i < 5; i ++)
    {
        DataRow row = dt.NewRow();
        row[0] = i;
        row[1] = i.ToString();
        dt.Rows.Add ( row );
    }

    // Now serialize the DataSet
    System.Xml.Serialization.XmlSerializer serializer = new XmlSerializer( typeof( DataSet ) );
    Stream stream = new FileStream( "DataSet.xml", FileMode.CreateNew);
    serializer.Serialize( stream, ds );

    // Clean up
    stream.Close();
}

结果如下:

<?xml version="1.0"?>
<DataSet>
 <xs:schema id="MyDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="MyDataSet" msdata:IsDataSet="true" msdata:Locale="en-GB">
        <xs:complexType>
            <xs:choice maxOccurs="unbounded">
                <xs:element name="MyDataTable">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="ID" type="xs:int" minOccurs="0" />
                            <xs:element name="Name" type="xs:string" minOccurs="0" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:choice>
        </xs:complexType>
    </xs:element>
 </xs:schema>
 <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    <MyDataSet>
        <MyDataTable diffgr:id="MyDataTable1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
            <ID>0</ID>
            <Name>0</Name>
        </MyDataTable>
        <MyDataTable diffgr:id="MyDataTable2" msdata:rowOrder="1" diffgr:hasChanges="inserted">
            <ID>1</ID>
            <Name>1</Name>
        </MyDataTable>
        <MyDataTable diffgr:id="MyDataTable3" msdata:rowOrder="2" diffgr:hasChanges="inserted">
            <ID>2</ID>
            <Name>2</Name>
        </MyDataTable>
        <MyDataTable diffgr:id="MyDataTable4" msdata:rowOrder="3" diffgr:hasChanges="inserted">
            <ID>3</ID>
            <Name>3</Name>
        </MyDataTable>
        <MyDataTable diffgr:id="MyDataTable5" msdata:rowOrder="4" diffgr:hasChanges="inserted">
            <ID>4</ID>
            <Name>4</Name>
        </MyDataTable>
    </MyDataSet>
 </diffgr:diffgram>
</DataSet>

 

复杂对象序列化

假如类的属性或是成员返回复杂对象(array 或者实例,XmlSerializer会把它转化为嵌套在xml文件里的成员,如下:

 

// Classes used in serializing. An Order object contains 0 or more Item objects
namespace XMLSerialization
{
    [Serializable]
    public class Item
    {
        public string strProductName;
        public int nProductID;

        public Item()
        {
            strProductName = "";
            nProductID = 0; 
        }
        public Item( string s, int n )
        {
            strProductName = s;
            nProductID = n;
        }
    }

    [Serializable]
    public class Order
    {
        // Must indicate what kind of elements exist in the ArrayList. See
        // Controlling XML Serialization Through Attributes
        [XmlElement( typeof(Item) )]
        public ArrayList alOrders;

        public Order()
        {
            alOrders = new ArrayList();
        }

        [XmlInclude( typeof( Item) )]
        public void Add( Item i )
        {
            alOrders.Add( i );
        }
    }
}

 

// The function creates an Order that contains many Items and then serializes the Order object
private void btnComplexOb_Click(object sender, System.EventArgs e)
{
    Stream stream = null;
    try
    {
        // Create an object that contains other objects
        XMLSerialization.Order order = new XMLSerialization.Order();
        order.Add( new XMLSerialization.Item( "Apples", 10 ) );
        order.Add( new XMLSerialization.Item( "Oranges", 20 ) );
        order.Add( new XMLSerialization.Item( "Avocados", 30 ) );

        // Now serialize the class
        System.Xml.Serialization.XmlSerializer serializer = new XmlSerializer( typeof( XMLSerialization.Order ) );
        stream = new FileStream( "ComplexObject.xml", FileMode.Create );
        serializer.Serialize( stream, order );
        stream.Close();
    }
    catch( Exception ex )
    {
        stream.Close();
        Trace.WriteLine ( ex.Message );
    }
}
<?xml version="1.0"?>
<Order xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <alOrders>
        <strProductName>Apples</strProductName>
        <nProductID>10</nProductID>
    </alOrders>
    <alOrders>
        <strProductName>Oranges</strProductName>
        <nProductID>20</nProductID>
    </alOrders>
    <alOrders>
        <strProductName>Avocados</strProductName>
        <nProductID>30</nProductID>
    </alOrders>
</Order>

 

 

 

 

 

posted @ 2014-03-11 14:40  Cathy Lee  阅读(526)  评论(0编辑  收藏  举报