使用属性控制 XML 序列化

属性可用于控制对象的 XML 序列化,或从同一类集中创建备用 XML 流。 有关创建备用 XML 流的详细信息,请参阅 如何:指定 XML 流的备用元素名称

注释

如果生成的 XML 必须符合万维网联盟(W3C)文档的第 5 节标题为 “简单对象访问协议(SOAP)1.1”,请使用 控制编码 SOAP 序列化的属性中列出的属性。

默认情况下,XML 元素名称由类或成员名称确定。 在名为 BookISBN 的类中,名为 ISBN 的字段将生成 XML 元素标记 <ISBN>,如以下示例所示:

Public Class Book
    Public ISBN As String
End Class
' When an instance of the Book class is serialized, it might
' produce this XML:
' <ISBN>1234567890</ISBN>.
public class Book
{
    public string ISBN;
}
// When an instance of the Book class is serialized, it might
// produce this XML:
// <ISBN>1234567890</ISBN>.

如果要为元素指定新名称,可以更改默认行为。 通过以下代码显示如何通过设置 XmlElementAttributeElementName 属性来实现此功能:

Public Class TaxRates
   < XmlElement(ElementName = "TaxRate")> _
    Public ReturnTaxRate As Decimal
End Class
public class TaxRates {
    [XmlElement(ElementName = "TaxRate")]
    public decimal ReturnTaxRate;
}

有关属性的详细信息,请参阅 “属性”。 有关控制 XML 序列化的属性的列表,请参阅 控制 XML 序列化的属性

控制数组序列化

属性XmlArrayAttributeXmlArrayItemAttribute控制数组的序列化。 使用这些属性,可以控制 W3C 文档中标题为 XML 架构第 2 部分:数据类型的元素名称、命名空间和 XML 架构 (XSD) 数据类型。 还可以指定可包含在数组中的类型。

XmlArrayAttribute 将决定数组在序列化时生成的外围 XML 元素的属性。 例如,默认情况下,序列化下面的数组将导致一个名为 EmployeesXML 元素。 该 Employees 元素将包含一系列以数组类型 Employee命名的元素。

Public Class Group
    Public Employees() As Employee
End Class
Public Class Employee
    Public Name As String
End Class
public class Group {
    public Employee[] Employees;
}
public class Employee {
    public string Name;
}

序列化实例可能类似于以下代码:

<Group>
<Employees>
    <Employee>
        <Name>Haley</Name>
    </Employee>
</Employees>
</Group>

通过应用 a XmlArrayAttribute,可以更改 XML 元素的名称,如下所示:

Public Class Group
    <XmlArray("TeamMembers")> _
    Public Employees() As Employee
End Class
public class Group {
    [XmlArray("TeamMembers")]
    public Employee[] Employees;
}

生成的 XML 可能类似于以下代码:

<Group>
<TeamMembers>
    <Employee>
        <Name>Haley</Name>
    </Employee>
</TeamMembers>
</Group>

另一方面,XmlArrayItemAttribute 用于控制数组中包含的项的序列化方式。

注释

该属性应用于返回数组的字段。

Public Class Group
    <XmlArrayItem("MemberName")> _
    Public Employee() As Employees
End Class
public class Group {
    [XmlArrayItem("MemberName")]
    public Employee[] Employees;
}

生成的 XML 可能类似于以下代码:

<Group>
<Employees>
    <MemberName>Haley</MemberName>
</Employees>
</Group>

序列化派生类

另一种 XmlArrayItemAttribute 用途是允许序列化派生类。 例如,可以向前面的示例添加另一个名为 Manager 派生自 Employee 的类。 如果不应用, XmlArrayItemAttribute代码将在运行时失败,因为无法识别派生类类型。 若要纠正此结果,请对每个可接受的类型(基类型和派生)应用属性两次,每次设置 Type 属性。

Public Class Group
    <XmlArrayItem(Type:=GetType(Employee)), _
    XmlArrayItem(Type:=GetType(Manager))> _
    Public Employees() As Employee
End Class
Public Class Employee
    Public Name As String
End Class
Public Class Manager
Inherits Employee
    Public Level As Integer
End Class
public class Group {
    [XmlArrayItem(Type = typeof(Employee)),
    XmlArrayItem(Type = typeof(Manager))]
    public Employee[] Employees;
}
public class Employee {
    public string Name;
}
public class Manager:Employee {
    public int Level;
}

序列化实例可能类似于以下代码:

<Group>
<Employees>
    <Employee>
        <Name>Haley</Name>
    </Employee>
    <Employee xsi:type = "Manager">
        <Name>Ann</Name>
        <Level>3</Level>
    </Employee>
</Employees>
</Group>

将数组序列化为元素序列

还可以通过将 XmlElementAttribute 应用于返回数组的字段,将数组序列化为平面结构的 XML 元素,如下所示:

Public Class Group
    <XmlElement> _
    Public Employees() As Employee
End Class
public class Group {
    [XmlElement]
    public Employee[] Employees;
}

序列化实例可能类似于以下代码:

<Group>
<Employees>
    <Name>Haley</Name>
</Employees>
<Employees>
    <Name>Noriko</Name>
</Employees>
<Employees>
    <Name>Marco</Name>
</Employees>
</Group>

区分两个 XML 流的另一种方法是使用 XML 架构定义工具从编译的代码生成 XML 架构 (XSD) 文档文件。 有关使用该工具的详细信息,请参阅 XML 架构定义工具和 XML 序列化。 如果未对字段应用任何属性,架构将按以下方式描述元素:

<xs:element minOccurs="0" maxOccurs ="1" name="Employees" type="ArrayOfEmployee" />

XmlElementAttribute 应用于字段时,生成的架构将元素描述如下:

<xs:element minOccurs="0" maxOccurs="unbounded" name="Employees" type="Employee" />

序列化 ArrayList

ArrayList 类可以包含各种对象的集合。 因此,可以像使用数组一样使用ArrayList。 相反,你可以创建一个字段来返回单个ArrayList,而不是返回类型化对象数组的字段。 但是,与数组一样,您必须通知 XmlSerializer 中的对象 ArrayList 所具有的类型。 为此,请为字段分配多个XmlElementAttribute实例,如以下示例所示。

Public Class Group
    <XmlElement(Type:=GetType(Employee)), _
    XmlElement(Type:=GetType(Manager))> _
    Public Info As ArrayList
End Class
public class Group {
    [XmlElement(Type = typeof(Employee)),
    XmlElement(Type = typeof(Manager))]
    public ArrayList Info;
}

使用 XmlRootAttribute 和 XmlTypeAttribute 控制类的序列化

只能将两个属性应用于类: XmlRootAttributeXmlTypeAttribute。 这些属性类似。 XmlRootAttribute该属性只能应用于一个类:序列化时表示 XML 文档的开始和结束元素的类,换句话说,是根元素。 XmlTypeAttribute另一方面,可以应用于任何类,包括根类。

例如,在前面的示例中,该 Group 类是根类,其所有公共字段和属性都将成为 XML 文档中找到的 XML 元素。 因此,只能有一个根类。 通过应用XmlRootAttribute,可以控制由XmlSerializer生成的 XML 流。 例如,可以更改元素名称和命名空间。

使用该 XmlTypeAttribute 控件可以控制生成的 XML 的架构。 需要通过 XML Web 服务发布架构时,此功能非常有用。 以下示例同时将 XmlTypeAttributeXmlRootAttribute 应用于同一类:

<XmlRoot("NewGroupName"), _
XmlType("NewTypeName")> _
Public Class Group
    Public Employees() As Employee
End Class
[XmlRoot("NewGroupName")]
[XmlType("NewTypeName")]
public class Group {
    public Employee[] Employees;
}

如果编译此类,并使用 XML 架构定义工具生成其模式,您将会看到以下 XML 描述 Group

<xs:element name="NewGroupName" type="NewTypeName" />

相比之下,如果要序列化类的实例,则在 XML 文档中只能找到 NewGroupName

<NewGroupName>
    . . .
</NewGroupName>

使用 XmlIgnoreAttribute 防止序列化

可能会遇到公共属性或字段不需要序列化的情况。 例如,字段或属性可用于包含元数据。 在这种情况下,将 XmlIgnoreAttribute 应用于字段或属性,XmlSerializer 将会跳过它。

另请参阅