Управление XML-сериализацией с использованием атрибутов

Атрибуты можно использовать для управления XML-сериализацией объекта или для создания альтернативного потока XML из того же набора классов. Дополнительные сведения о создании альтернативного потока XML см. в разделе Как указать имя альтернативного элемента для потока XML.

2baksw0z.note(ru-ru,VS.100).gifПримечание
Если сгенерированные XML должны удовлетворять требованиями раздела 5 документа "Протокол SOAP 1.1" консорциума World Wide Web (www.w3.org), используйте атрибуты, указанные в разделе Атрибуты управления SOAP-сериализацией с кодировкой.

По умолчанию имя элемента XML определяется классом или именем члена. Как показано в следующем примере, в простом классе с именем Book поле с именем 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>.

Поведение по умолчанию можно изменить, если элементу следует присвоить новое имя. В следующем примере кода показано, как это можно сделать с помощью атрибута, задав свойство ElementName XmlElementAttribute.

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

Дополнительные сведения об атрибутах см. в разделе Extending Metadata Using Attributes. Список атрибутов, управляющих сериализацией XML, см. в разделе Атрибуты управления XML-сериализацией.

Управление сериализацией массивов

Атрибуты XmlArrayAttribute и XmlArrayItemAttribute предназначены для управления сериализацией массивов. С помощью этих атрибутов можно управлять именем элемента, пространством имен и типом данных схемы XML (XSD) (согласно документу "Схема XML, часть 2: типы данных" консорциума World Wide Web (www.w3.org)). Также можно указать типы, которые можно включить в массив.

XmlArrayAttribute определяет свойства включающего элемента XML, который создается при сериализации массива. Например, по умолчанию при сериализации массива ниже будет создан элемент XML с именем Employees. Элемент 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>

Применив 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>

С другой стороны, атрибут 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>

Сериализация массива как последовательности элементов

Также предусмотрена возможность сериализации массива как плоской последовательности элементов XML путем применения XmlElementAttribute к полю, возвращающему массив следующим образом.

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

К классу (и только к одному классу) можно применить два атрибута: XmlRootAttribute и XmlTypeAttribute. Эти атрибуты в значительной степени схожи. Атрибут XmlRootAttribute можно применить только к одному классу, классу, который при сериализации представляет открывающий и закрывающий элемент документа XML, другими словами, корневой элемент. С другой стороны, атрибут XmlTypeAttribute можно применить к любому классу, включая корневой.

В предыдущих примерах класс Group является корневым, и все его открытые поля и свойства становятся элементами XML, находящимися в документе XML. Поэтому может существовать только один корневой класс. Применяя XmlRootAttribute, можно управлять потоком XML, созданным с помощью XmlSerializer. Например, можно изменить имя элемента и пространство имен.

Атрибут XmlTypeAttribute обеспечивает управление схемой созданного XML. Такая возможность полезна, когда необходимо опубликовать схему через XML-веб-службу. В следующем примере применяются XmlTypeAttribute и XmlRootAttribute к одному и тому же классу.

<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 его пропустит.

См. также

Задачи

Как указать имя альтернативного элемента для потока XML
Как сериализовать объект
Как десериализовать объект

Основные понятия

Атрибуты управления XML-сериализацией
Атрибуты управления SOAP-сериализацией с кодировкой
Введение в XML-сериализацию
Примеры XML-сериализации